Rev 578 | Rev 583 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 578 | Rev 579 | ||
---|---|---|---|
Line 49... | Line 49... | ||
49 | } |
49 | } |
50 | 50 | ||
51 | // JWT handling |
51 | // JWT handling |
52 | 52 | ||
53 | const JWT_GENERATOR_AJAX = 0; |
53 | const JWT_GENERATOR_AJAX = 0; |
54 | //const JWT_GENERATOR_LOGIN = 1; |
54 | const JWT_GENERATOR_LOGIN = 1; |
55 | const JWT_GENERATOR_MANUAL = 2; |
55 | const JWT_GENERATOR_MANUAL = 2; |
56 | 56 | ||
57 | private function jwtGetBlacklistConfigKey($gen, $sub) { |
57 | private function jwtGetBlacklistConfigKey($gen, $sub) { |
58 | // Note: Needs to be <= 50 characters! |
58 | // Note: Needs to be <= 50 characters! |
59 | return 'jwt_blacklist_gen('.$gen.')_sub('.trim(base64_encode(md5($sub,true)),'=').')'; |
59 | return 'jwt_blacklist_gen('.$gen.')_sub('.trim(base64_encode(md5($sub,true)),'=').')'; |
Line 63... | Line 63... | ||
63 | $cfg = $this->jwtGetBlacklistConfigKey($gen, $sub); |
63 | $cfg = $this->jwtGetBlacklistConfigKey($gen, $sub); |
64 | $bl_time = time()-1; |
64 | $bl_time = time()-1; |
65 | 65 | ||
66 | $gen_desc = 'Unknown'; |
66 | $gen_desc = 'Unknown'; |
67 | if ($gen === self::JWT_GENERATOR_AJAX) $gen_desc = 'Automated AJAX calls'; |
67 | if ($gen === self::JWT_GENERATOR_AJAX) $gen_desc = 'Automated AJAX calls'; |
68 | //if ($gen === self::JWT_GENERATOR_LOGIN) $gen_desc = 'Login'; |
68 | if ($gen === self::JWT_GENERATOR_LOGIN) $gen_desc = 'Login'; |
69 | if ($gen === self::JWT_GENERATOR_MANUAL) $gen_desc = 'Manually created'; |
69 | if ($gen === self::JWT_GENERATOR_MANUAL) $gen_desc = 'Manually created'; |
70 | 70 | ||
71 | OIDplus::config()->prepareConfigKey($cfg, 'Revoke timestamp of all JWT tokens for $sub with generator $gen ($gen_desc)', $bl_time, OIDplusConfig::PROTECTION_HIDDEN, function($value) {}); |
71 | OIDplus::config()->prepareConfigKey($cfg, 'Revoke timestamp of all JWT tokens for $sub with generator $gen ($gen_desc)', $bl_time, OIDplusConfig::PROTECTION_HIDDEN, function($value) {}); |
72 | OIDplus::config()->setValue($cfg, $bl_time); |
72 | OIDplus::config()->setValue($cfg, $bl_time); |
73 | } |
73 | } |
Line 94... | Line 94... | ||
94 | else if (($sub !== 'admin') && !OIDplus::baseConfig()->getValue('JWT_ALLOW_AJAX_USER', true)) { |
94 | else if (($sub !== 'admin') && !OIDplus::baseConfig()->getValue('JWT_ALLOW_AJAX_USER', true)) { |
95 | // Generator: plugins/raPages/910_automated_ajax_calls/OIDplusPageRaAutomatedAJAXCalls.class.php |
95 | // Generator: plugins/raPages/910_automated_ajax_calls/OIDplusPageRaAutomatedAJAXCalls.class.php |
96 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_AJAX_USER')); |
96 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_AJAX_USER')); |
97 | } |
97 | } |
98 | } |
98 | } |
99 | /* else if ($gen === self::JWT_GENERATOR_LOGIN) { |
99 | else if ($gen === self::JWT_GENERATOR_LOGIN) { |
100 | // Reserved for future use (use JWT token in a cookie as alternative to PHP session): |
100 | // Used for feature "stay logged in" (use JWT token in a cookie as alternative to PHP session): |
- | 101 | // - No PHP session will be used |
|
- | 102 | // - Session will not be bound to IP address (therefore, you can switch between mobile/WiFi for example) |
|
- | 103 | // - No server-side session needed |
|
101 | if (($sub === 'admin') && !OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_ADMIN', true)) { |
104 | if (($sub === 'admin') && !OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_ADMIN', true)) { |
102 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_ADMIN')); |
105 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_ADMIN')); |
103 | } |
106 | } |
104 | else if (($sub !== 'admin') && !OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_USER', true)) { |
107 | else if (($sub !== 'admin') && !OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_USER', true)) { |
105 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_USER')); |
108 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_USER')); |
106 | } |
109 | } |
107 | } */ |
110 | } |
108 | else if ($gen === self::JWT_GENERATOR_MANUAL) { |
111 | else if ($gen === self::JWT_GENERATOR_MANUAL) { |
109 | // Generator 2 are "hand-crafted" tokens |
112 | // Generator 2 are "hand-crafted" tokens |
110 | if (!OIDplus::baseConfig()->getValue('JWT_ALLOW_MANUAL', true)) { |
113 | if (!OIDplus::baseConfig()->getValue('JWT_ALLOW_MANUAL', true)) { |
111 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_MANUAL')); |
114 | throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_MANUAL')); |
112 | } |
115 | } |
Line 131... | Line 134... | ||
131 | throw new OIDplusException(_L('Your IP address is not allowed to use this token')); |
134 | throw new OIDplusException(_L('Your IP address is not allowed to use this token')); |
132 | } |
135 | } |
133 | } |
136 | } |
134 | 137 | ||
135 | // Checks which are dependent on the generator |
138 | // Checks which are dependent on the generator |
- | 139 | if ($gen === self::JWT_GENERATOR_LOGIN) { |
|
- | 140 | if (!isset($_COOKIE['OIDPLUS_AUTH_JWT'])) { |
|
- | 141 | throw new OIDplusException(_L('This kind of JWT token can only be used with the %1 request type','COOKIE')); |
|
- | 142 | } |
|
- | 143 | } |
|
136 | if ($gen === self::JWT_GENERATOR_AJAX) { |
144 | if ($gen === self::JWT_GENERATOR_AJAX) { |
- | 145 | if (!isset($_GET['OIDPLUS_AUTH_JWT']) && !isset($_POST['OIDPLUS_AUTH_JWT'])) { |
|
- | 146 | throw new OIDplusException(_L('This kind of JWT token can only be used with the %1 request type','GET/POST')); |
|
- | 147 | } |
|
137 | if (isset($_SERVER['SCRIPT_FILENAME']) && (strtolower(basename($_SERVER['SCRIPT_FILENAME'])) !== 'ajax.php')) { |
148 | if (isset($_SERVER['SCRIPT_FILENAME']) && (strtolower(basename($_SERVER['SCRIPT_FILENAME'])) !== 'ajax.php')) { |
138 | throw new OIDplusException(_L('This kind of JWT token can only be used in ajax.php')); |
149 | throw new OIDplusException(_L('This kind of JWT token can only be used in ajax.php')); |
139 | } |
150 | } |
140 | } |
151 | } |
141 | } |
152 | } |
Line 144... | Line 155... | ||
144 | 155 | ||
145 | protected function getAuthContentStore() { |
156 | protected function getAuthContentStore() { |
146 | static $contentProvider = null; |
157 | static $contentProvider = null; |
147 | 158 | ||
148 | if (is_null($contentProvider)) { |
159 | if (is_null($contentProvider)) { |
- | 160 | $jwt = ''; |
|
- | 161 | if (isset($_COOKIE['OIDPLUS_AUTH_JWT'])) $jwt = $_COOKIE['OIDPLUS_AUTH_JWT']; |
|
149 | if (isset($_REQUEST['OIDPLUS_AUTH_JWT'])) { |
162 | if (isset($_POST['OIDPLUS_AUTH_JWT'])) $jwt = $_POST['OIDPLUS_AUTH_JWT']; |
- | 163 | if (isset($_GET['OIDPLUS_AUTH_JWT'])) $jwt = $_GET['OIDPLUS_AUTH_JWT']; |
|
- | 164 | ||
- | 165 | if (!empty($jwt)) { |
|
150 | $contentProvider = new OIDplusAuthContentStoreJWT(); |
166 | $contentProvider = new OIDplusAuthContentStoreJWT(); |
151 | 167 | ||
152 | try { |
168 | try { |
153 | // Decode the JWT. In this step, the signature as well as EXP/NBF times will be checked |
169 | // Decode the JWT. In this step, the signature as well as EXP/NBF times will be checked |
154 | $contentProvider->loadJWT($_REQUEST['OIDPLUS_AUTH_JWT']); |
170 | $contentProvider->loadJWT($jwt); |
155 | 171 | ||
156 | // Do various checks if the token is allowed and not blacklisted |
172 | // Do various checks if the token is allowed and not blacklisted |
157 | $this->jwtSecurityCheck($contentProvider); |
173 | $this->jwtSecurityCheck($contentProvider); |
158 | } catch (Exception $e) { |
174 | } catch (Exception $e) { |
- | 175 | if (isset($_GET['OIDPLUS_AUTH_JWT']) || isset($_POST['OIDPLUS_AUTH_JWT'])) { |
|
- | 176 | // Most likely an AJAX request. We can throw an Exception |
|
159 | $contentProvider = null; |
177 | $contentProvider = null; |
160 | throw new OIDplusException(_L('The JWT token was rejected: %1',$e->getMessage())); |
178 | throw new OIDplusException(_L('The JWT token was rejected: %1',$e->getMessage())); |
- | 179 | } else { |
|
- | 180 | // Most likely an expired Cookie/Login session. We must not throw an Exception, otherwise we will break jsTree |
|
- | 181 | $contentProvider = new OIDplusAuthContentStoreSession(); |
|
- | 182 | OIDplus::cookieUtils()->unsetcookie('OIDPLUS_AUTH_JWT'); |
|
- | 183 | } |
|
161 | } |
184 | } |
162 | } else { |
185 | } else { |
163 | // Normal login via web-browser |
186 | // Normal login via web-browser |
164 | $contentProvider = new OIDplusAuthContentStoreSession(); |
187 | $contentProvider = new OIDplusAuthContentStoreSession(); |
165 | } |
188 | } |