Subversion Repositories oidplus

Rev

Rev 1303 | Rev 1306 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1303 Rev 1305
Line 22... Line 22...
22
// phpcs:disable PSR1.Files.SideEffects
22
// phpcs:disable PSR1.Files.SideEffects
23
\defined('INSIDE_OIDPLUS') or die;
23
\defined('INSIDE_OIDPLUS') or die;
24
// phpcs:enable PSR1.Files.SideEffects
24
// phpcs:enable PSR1.Files.SideEffects
25
 
25
 
26
/**
26
/**
27
 * Auth content store for JWT tokens ("Remember me" cookies, Automated AJAX argument, or REST Bearer)
27
 * Auth content store for JWT tokens (web browser login cookies, Automated AJAX argument, or REST Bearer)
28
 */
28
 */
29
class OIDplusAuthContentStoreJWT extends OIDplusAuthContentStore {
29
class OIDplusAuthContentStoreJWT {
30
 
30
 
31
        /**
31
        /**
32
         * Cookie name for the JWT auth token
32
         * Cookie name for the JWT auth token
33
         */
33
         */
34
        const COOKIE_NAME = 'OIDPLUS_AUTH_JWT';
34
        const COOKIE_NAME = 'OIDPLUS_AUTH_JWT';
35
 
35
 
36
        /**
36
        /**
-
 
37
         * Token generator; must be one of OIDplusAuthContentStoreJWT::JWT_GENERATOR_*
-
 
38
         */
-
 
39
        const CLAIM_GENERATOR = 'urn:oid:1.3.6.1.4.1.37476.2.5.2.7.1';
-
 
40
 
-
 
41
        /**
-
 
42
         * List of logged-in users
-
 
43
         */
-
 
44
        const CLAIM_LOGIN_LIST = 'urn:oid:1.3.6.1.4.1.37476.2.5.2.7.2';
-
 
45
 
-
 
46
        /**
-
 
47
         * SSH = Server Secret Hash
-
 
48
         */
-
 
49
        const CLAIM_SSH = 'urn:oid:1.3.6.1.4.1.37476.2.5.2.7.3';
-
 
50
 
-
 
51
        /**
-
 
52
         * IP-Adress limit
-
 
53
         */
-
 
54
        const CLAIM_LIMIT_IP = 'urn:oid:1.3.6.1.4.1.37476.2.5.2.7.4';
-
 
55
 
-
 
56
        /**
37
         * "Automated AJAX" plugin
57
         * "Automated AJAX" plugin
38
         */
58
         */
39
        const JWT_GENERATOR_AJAX   = 10;
59
        const JWT_GENERATOR_AJAX   = 10;
40
        /**
60
        /**
41
         * "REST API" plugin
61
         * "REST API" plugin
42
         */
62
         */
43
        const JWT_GENERATOR_REST   = 20;
63
        const JWT_GENERATOR_REST   = 20;
44
        /**
64
        /**
45
         * "Remember me" login method
65
         * Web browser login method
46
         */
66
         */
47
        const JWT_GENERATOR_LOGIN  = 40;
67
        const JWT_GENERATOR_LOGIN  = 40;
48
        /**
68
        /**
49
         * "Manually crafted" JWT tokens
69
         * "Manually crafted" JWT tokens
50
         */
70
         */
Line 65... Line 85...
65
         */
85
         */
66
        private static function generatorName($gen) {
86
        private static function generatorName($gen) {
67
                // Note: The strings are not translated, because the name is used in config keys or logs
87
                // Note: The strings are not translated, because the name is used in config keys or logs
68
                if ($gen === self::JWT_GENERATOR_AJAX)   return 'Automated AJAX calls';
88
                if ($gen === self::JWT_GENERATOR_AJAX)   return 'Automated AJAX calls';
69
                if ($gen === self::JWT_GENERATOR_REST)   return 'REST API';
89
                if ($gen === self::JWT_GENERATOR_REST)   return 'REST API';
70
                if ($gen === self::JWT_GENERATOR_LOGIN)  return 'Login ("Remember me")';
90
                if ($gen === self::JWT_GENERATOR_LOGIN)  return 'Browser login';
71
                if ($gen === self::JWT_GENERATOR_MANUAL) return 'Manually created';
91
                if ($gen === self::JWT_GENERATOR_MANUAL) return 'Manually created';
72
                return 'Unknown generator';
92
                return 'Unknown generator';
73
        }
93
        }
74
 
94
 
75
        /**
95
        /**
Line 82... Line 102...
82
                $cfg = self::jwtGetBlacklistConfigKey($gen, $sub);
102
                $cfg = self::jwtGetBlacklistConfigKey($gen, $sub);
83
                $bl_time = time()-1;
103
                $bl_time = time()-1;
84
 
104
 
85
                $gen_desc = self::generatorName($gen);
105
                $gen_desc = self::generatorName($gen);
86
 
106
 
87
                OIDplus::config()->prepareConfigKey($cfg, 'Revoke timestamp of all JWT tokens for $sub with generator $gen ($gen_desc)', "$bl_time", OIDplusConfig::PROTECTION_HIDDEN, function($value) {});
107
                OIDplus::config()->prepareConfigKey($cfg, "Revoke timestamp of all JWT tokens for $sub with generator $gen ($gen_desc)", "$bl_time", OIDplusConfig::PROTECTION_HIDDEN, function($value) {});
88
                OIDplus::config()->setValue($cfg, $bl_time);
108
                OIDplus::config()->setValue($cfg, $bl_time);
89
        }
109
        }
90
 
110
 
91
        /**
111
        /**
92
         * @param int $gen OIDplusAuthContentStoreJWT::JWT_GENERATOR_...
112
         * @param int $gen OIDplusAuthContentStoreJWT::JWT_GENERATOR_...
Line 103... Line 123...
103
         * We include a hash of the server-secret here (ssh = server-secret-hash), so that the JWT can be invalidated by changing the server-secret
123
         * We include a hash of the server-secret here (ssh = server-secret-hash), so that the JWT can be invalidated by changing the server-secret
104
         * @return string
124
         * @return string
105
         * @throws OIDplusException
125
         * @throws OIDplusException
106
         */
126
         */
107
        private static function getSsh(): string {
127
        private static function getSsh(): string {
108
                return OIDplus::authUtils()->makeSecret(['bb1aebd6-fe6a-11ed-a553-3c4a92df8582']);
128
                $hexadecimal_string = OIDplus::authUtils()->makeSecret(['bb1aebd6-fe6a-11ed-a553-3c4a92df8582']);
-
 
129
                return base64_encode(pack('H*',$hexadecimal_string));
109
        }
130
        }
110
 
131
 
111
        /**
132
        /**
112
         * Do various checks if the token is allowed and not blacklisted
133
         * Do various checks if the token is allowed and not blacklisted
113
         * @param OIDplusAuthContentStore $contentProvider
134
         * @param OIDplusAuthContentStoreJWT $contentProvider
114
         * @param int|null $validGenerators Bitmask which generators to allow (null = allow all)
135
         * @param int|null $validGenerators Bitmask which generators to allow (null = allow all)
115
         * @return void
136
         * @return void
116
         * @throws OIDplusException
137
         * @throws OIDplusException
117
         */
138
         */
118
        private static function jwtSecurityCheck(OIDplusAuthContentStore $contentProvider, int $validGenerators=null) {
139
        private static function jwtSecurityCheck(OIDplusAuthContentStoreJWT $contentProvider, int $validGenerators=null) {
119
                // Check if the token is intended for us
140
                // Check if the token is intended for us
120
                if ($contentProvider->getValue('aud','') !== OIDplus::getEditionInfo()['jwtaud']) {
141
                if ($contentProvider->getValue('aud','') !== OIDplus::getEditionInfo()['jwtaud']) {
121
                        throw new OIDplusException(_L('Token has wrong audience'));
142
                        throw new OIDplusException(_L('Token has wrong audience'));
122
                }
143
                }
123
 
144
 
124
                if ($contentProvider->getValue('oidplus_ssh', '') !== self::getSsh()) {
145
                if ($contentProvider->getValue(self::CLAIM_SSH, '') !== self::getSsh()) {
125
                        throw new OIDplusException(_L('"Server Secret" was changed; therefore the JWT is not valid anymore'));
146
                        throw new OIDplusException(_L('"Server Secret" was changed; therefore the JWT is not valid anymore'));
126
                }
147
                }
127
 
148
 
128
                $gen = $contentProvider->getValue('oidplus_generator', -1);
149
                $gen = $contentProvider->getValue(self::CLAIM_GENERATOR, -1);
129
 
150
 
130
                $has_admin = $contentProvider->isAdminLoggedIn();
151
                $has_admin = $contentProvider->isAdminLoggedIn();
131
                $has_ra = $contentProvider->raNumLoggedIn() > 0;
152
                $has_ra = $contentProvider->raNumLoggedIn() > 0;
132
 
153
 
133
                // Check if the token generator is allowed
154
                // Check if the token generator is allowed
Line 150... Line 171...
150
                                // Generator: plugins/viathinksoft/raPages/911_rest_api/OIDplusPageRaRestApi.class.php
171
                                // Generator: plugins/viathinksoft/raPages/911_rest_api/OIDplusPageRaRestApi.class.php
151
                                throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_REST_USER'));
172
                                throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_REST_USER'));
152
                        }
173
                        }
153
                }
174
                }
154
                else if ($gen === self::JWT_GENERATOR_LOGIN) {
175
                else if ($gen === self::JWT_GENERATOR_LOGIN) {
155
                        // Used for feature "Remember me" (use JWT token in a cookie as alternative to PHP session):
176
                        // Used for web browser login (use JWT token in a cookie as alternative to PHP session):
156
                        // - No PHP session will be used
177
                        // - No PHP session will be used
157
                        // - Session will not be bound to IP address (therefore, you can switch between mobile/WiFi for example)
178
                        // - Session will not be bound to IP address (therefore, you can switch between mobile/WiFi for example)
158
                        // - No server-side session needed
179
                        // - No server-side session needed
159
                        if (($has_admin) && !OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_ADMIN', true)) {
180
                        if (($has_admin) && !OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_ADMIN', true)) {
160
                                throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_ADMIN'));
181
                                throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_ADMIN'));
Line 175... Line 196...
175
                        throw new OIDplusException(_L('Token generator %1 not recognized',$gen));
196
                        throw new OIDplusException(_L('Token generator %1 not recognized',$gen));
176
                }
197
                }
177
 
198
 
178
                // Make sure that the IAT (issued at time) isn't in a blacklisted timeframe
199
                // Make sure that the IAT (issued at time) isn't in a blacklisted timeframe
179
                // When an user believes that a token was compromised, then they can blacklist the tokens identified by their "iat" ("Issued at") property
200
                // When an user believes that a token was compromised, then they can blacklist the tokens identified by their "iat" ("Issued at") property
180
                // When a user logs out of a "remember me" session, the JWT token will be blacklisted as well
201
                // When a user logs out of a web browser session, the JWT token will be blacklisted as well
181
                // Small side effect: All "remember me" sessions of that user will be revoked then
202
                // Small side effect: All web browser login sessions of that user will be revoked then
182
                $iat = $contentProvider->getValue('iat',0);
203
                $iat = $contentProvider->getValue('iat',0);
183
                if (($iat-120/*leeway 2min*/) > time()) {
204
                if (($iat-120/*leeway 2min*/) > time()) {
184
                        // Token was created in the future. Something is wrong!
205
                        // Token was created in the future. Something is wrong!
185
                        throw new OIDplusException(_L('JWT Token cannot be verified because the server time is wrong'));
206
                        throw new OIDplusException(_L('JWT Token cannot be verified because the server time is wrong'));
186
                }
207
                }
Line 198... Line 219...
198
                        }
219
                        }
199
                }
220
                }
200
 
221
 
201
                // Optional feature: Limit the JWT to a specific IP address
222
                // Optional feature: Limit the JWT to a specific IP address
202
                // Currently not used in OIDplus
223
                // Currently not used in OIDplus
203
                $ip = $contentProvider->getValue('oidplus_limit_ip','');
224
                $ip = $contentProvider->getValue(self::CLAIM_LIMIT_IP, null);
204
                if ($ip !== '') {
225
                if (!is_null($ip)) {
205
                        if (isset($_SERVER['REMOTE_ADDR']) && ($ip !== $_SERVER['REMOTE_ADDR'])) {
226
                        if (isset($_SERVER['REMOTE_ADDR']) && ($ip !== $_SERVER['REMOTE_ADDR'])) {
206
                                throw new OIDplusException(_L('Your IP address is not allowed to use this token'));
227
                                throw new OIDplusException(_L('Your IP address is not allowed to use this token'));
207
                        }
228
                        }
208
                }
229
                }
209
 
230
 
Line 280... Line 301...
280
         */
301
         */
281
        public function destroySession() {
302
        public function destroySession() {
282
                OIDplus::cookieUtils()->unsetcookie(self::COOKIE_NAME);
303
                OIDplus::cookieUtils()->unsetcookie(self::COOKIE_NAME);
283
        }
304
        }
284
 
305
 
-
 
306
        // RA authentication functions (low-level)
-
 
307
 
-
 
308
        /**
-
 
309
         * @param string $email
-
 
310
         * @return void
-
 
311
         */
-
 
312
        public function raLogin(string $email) {
-
 
313
                if ($email == 'admin') return;
-
 
314
 
-
 
315
                $list = $this->getValue(self::CLAIM_LOGIN_LIST, null);
-
 
316
                if (is_null($list)) $list = [];
-
 
317
                if (!in_array($email, $list)) $list[] = $email;
-
 
318
                $this->setValue(self::CLAIM_LOGIN_LIST, $list);
-
 
319
        }
-
 
320
 
-
 
321
        /**
-
 
322
         * @return int
-
 
323
         */
-
 
324
        public function raNumLoggedIn(): int {
-
 
325
                return count($this->loggedInRaList());
-
 
326
        }
-
 
327
 
-
 
328
        /**
-
 
329
         * @return OIDplusRA[]
-
 
330
         */
-
 
331
        public function loggedInRaList(): array {
-
 
332
                $list = $this->getValue(self::CLAIM_LOGIN_LIST, null);
-
 
333
                if (is_null($list)) $list = [];
-
 
334
 
-
 
335
                $res = array();
-
 
336
                foreach (array_unique($list) as $username) {
-
 
337
                        if ($username == '') continue; // should not happen
-
 
338
                        if ($username == 'admin') continue;
-
 
339
                        $res[] = new OIDplusRA($username);
-
 
340
                }
-
 
341
                return $res;
-
 
342
        }
-
 
343
 
-
 
344
        /**
-
 
345
         * @param string $email
-
 
346
         * @return bool
-
 
347
         */
-
 
348
        public function isRaLoggedIn(string $email): bool {
-
 
349
                foreach ($this->loggedInRaList() as $ra) {
-
 
350
                        if ($email == $ra->raEmail()) return true;
-
 
351
                }
-
 
352
                return false;
-
 
353
        }
-
 
354
 
285
        /**
355
        /**
286
         * @param string $email
356
         * @param string $email
287
         * @return void
357
         * @return void
288
         * @throws OIDplusException
358
         * @throws OIDplusException
289
         */
359
         */
290
        public function raLogout(string $email) {
360
        public function raLogout(string $email) {
-
 
361
                if ($email == 'admin') return;
-
 
362
 
291
                $gen = $this->getValue('oidplus_generator', -1);
363
                $gen = $this->getValue(self::CLAIM_GENERATOR, -1);
292
                if ($gen >= 0) self::jwtBlacklist($gen, $email);
364
                if ($gen >= 0) self::jwtBlacklist($gen, $email);
-
 
365
 
-
 
366
                $list = $this->getValue(self::CLAIM_LOGIN_LIST, null);
-
 
367
                if (is_null($list)) $list = [];
293
                parent::raLogout($email);
368
                $key = array_search($email, $list);
-
 
369
                if ($key !== false) unset($list[$key]);
-
 
370
                $this->setValue(self::CLAIM_LOGIN_LIST, $list);
294
        }
371
        }
295
 
372
 
296
        /**
373
        /**
297
         * @param string $email
374
         * @param string $email
298
         * @param string $loginfo
375
         * @param string $loginfo
Line 302... Line 379...
302
        public function raLogoutEx(string $email, string &$loginfo) {
379
        public function raLogoutEx(string $email, string &$loginfo) {
303
                $this->raLogout($email);
380
                $this->raLogout($email);
304
                $loginfo = 'from JWT session';
381
                $loginfo = 'from JWT session';
305
        }
382
        }
306
 
383
 
-
 
384
        // Admin authentication functions (low-level)
-
 
385
 
-
 
386
        /**
-
 
387
         * @return void
-
 
388
         */
-
 
389
        public function adminLogin() {
-
 
390
                $list = $this->getValue(self::CLAIM_LOGIN_LIST, null);
-
 
391
                if (is_null($list)) $list = [];
-
 
392
                if (!in_array('admin', $list)) $list[] = 'admin';
-
 
393
                $this->setValue(self::CLAIM_LOGIN_LIST, $list);
-
 
394
        }
-
 
395
 
-
 
396
        /**
-
 
397
         * @return bool
-
 
398
         */
-
 
399
        public function isAdminLoggedIn(): bool {
-
 
400
                $list = $this->getValue(self::CLAIM_LOGIN_LIST, null);
-
 
401
                if (is_null($list)) $list = [];
-
 
402
                return in_array('admin', $list);
-
 
403
        }
-
 
404
 
307
        /**
405
        /**
308
         * @return void
406
         * @return void
309
         * @throws OIDplusException
407
         * @throws OIDplusException
310
         */
408
         */
311
        public function adminLogout() {
409
        public function adminLogout() {
312
                $gen = $this->getValue('oidplus_generator', -1);
410
                $gen = $this->getValue(self::CLAIM_GENERATOR, -1);
313
                if ($gen >= 0) self::jwtBlacklist($gen, 'admin');
411
                if ($gen >= 0) self::jwtBlacklist($gen, 'admin');
-
 
412
 
-
 
413
                $list = $this->getValue(self::CLAIM_LOGIN_LIST, null);
-
 
414
                if (is_null($list)) $list = [];
314
                parent::adminLogout();
415
                $key = array_search('admin', $list);
-
 
416
                if ($key !== false) unset($list[$key]);
-
 
417
                $this->setValue(self::CLAIM_LOGIN_LIST, $list);
315
        }
418
        }
316
 
419
 
317
        /**
420
        /**
318
         * @param string $loginfo
421
         * @param string $loginfo
319
         * @return void
422
         * @return void
Line 325... Line 428...
325
        }
428
        }
326
 
429
 
327
        private static $contentProvider = null;
430
        private static $contentProvider = null;
328
 
431
 
329
        /**
432
        /**
330
         * @return OIDplusAuthContentStore|null
433
         * @return OIDplusAuthContentStoreJWT|null
331
         * @throws OIDplusException
434
         * @throws OIDplusException
332
         */
435
         */
333
        public static function getActiveProvider()/*: ?OIDplusAuthContentStore*/ {
436
        public static function getActiveProvider()/*: ?OIDplusAuthContentStoreJWT*/ {
334
                if (!self::$contentProvider) {
437
                if (!self::$contentProvider) {
335
 
438
 
336
                        $tmp = null;
439
                        $tmp = null;
337
                        $silent_error = false;
440
                        $silent_error = false;
338
 
441
 
Line 350... Line 453...
350
                                                self::jwtSecurityCheck($tmp, self::JWT_GENERATOR_REST | self::JWT_GENERATOR_MANUAL);
453
                                                self::jwtSecurityCheck($tmp, self::JWT_GENERATOR_REST | self::JWT_GENERATOR_MANUAL);
351
                                        }
454
                                        }
352
 
455
 
353
                                } else {
456
                                } else {
354
 
457
 
355
                                        // A web-visitor (HTML and AJAX, but not REST) can use a JWT "remember me" Cookie
458
                                        // A web-visitor (HTML and AJAX, but not REST) can use a JWT Cookie
356
                                        if (isset($_COOKIE[self::COOKIE_NAME])) {
459
                                        if (isset($_COOKIE[self::COOKIE_NAME])) {
357
                                                $silent_error = true;
460
                                                $silent_error = true;
358
                                                $tmp = new OIDplusAuthContentStoreJWT();
461
                                                $tmp = new OIDplusAuthContentStoreJWT();
359
                                                $tmp->loadJWT($_COOKIE[self::COOKIE_NAME]);
462
                                                $tmp->loadJWT($_COOKIE[self::COOKIE_NAME]);
360
                                                self::jwtSecurityCheck($tmp, self::JWT_GENERATOR_LOGIN | self::JWT_GENERATOR_MANUAL);
463
                                                self::jwtSecurityCheck($tmp, self::JWT_GENERATOR_LOGIN | self::JWT_GENERATOR_MANUAL);
361
                                        }
464
                                        }
362
 
465
 
363
                                        // AJAX may additionally use GET/POST automated AJAX (in addition to the normal JWT "remember me" Cookie)
466
                                        // AJAX may additionally use GET/POST automated AJAX (in addition to the normal web browser login Cookie)
364
                                        if (isset($_SERVER['SCRIPT_FILENAME']) && (strtolower(basename($_SERVER['SCRIPT_FILENAME'])) !== 'ajax.php')) {
467
                                        if (isset($_SERVER['SCRIPT_FILENAME']) && (strtolower(basename($_SERVER['SCRIPT_FILENAME'])) !== 'ajax.php')) {
365
                                                if (isset($_POST[self::COOKIE_NAME])) {
468
                                                if (isset($_POST[self::COOKIE_NAME])) {
366
                                                        $silent_error = false;
469
                                                        $silent_error = false;
367
                                                        $tmp = new OIDplusAuthContentStoreJWT();
470
                                                        $tmp = new OIDplusAuthContentStoreJWT();
368
                                                        $tmp->loadJWT($_POST[self::COOKIE_NAME]);
471
                                                        $tmp->loadJWT($_POST[self::COOKIE_NAME]);
Line 405... Line 508...
405
                if (is_null(self::getActiveProvider())) {
508
                if (is_null(self::getActiveProvider())) {
406
                        $this->raLogin($email);
509
                        $this->raLogin($email);
407
                        $loginfo = 'into new JWT session';
510
                        $loginfo = 'into new JWT session';
408
                        self::$contentProvider = $this;
511
                        self::$contentProvider = $this;
409
                } else {
512
                } else {
410
                        $gen = $this->getValue('oidplus_generator',-1);
513
                        $gen = $this->getValue(self::CLAIM_GENERATOR,-1);
411
                        switch ($gen) {
514
                        switch ($gen) {
412
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_AJAX :
515
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_AJAX :
413
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_REST :
516
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_REST :
414
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_MANUAL :
517
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_MANUAL :
415
                                        throw new OIDplusException(_L('This kind of JWT token cannot be altered. Therefore you cannot do this action.'));
518
                                        throw new OIDplusException(_L('This kind of JWT token cannot be altered. Therefore you cannot do this action.'));
416
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_LOGIN :
519
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_LOGIN :
417
                                        if (!OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_USER', true)) {
520
                                        if (!OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_USER', true)) {
418
                                                throw new OIDplusException(_L('You cannot add this login credential to your existing "remember me" session. You need to log-out first.'));
521
                                                throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_USER'));
419
                                        }
522
                                        }
420
                                        break;
523
                                        break;
421
                                default:
524
                                default:
422
                                        assert(false); // This cannot happen because jwtSecurityCheck will check for unknown generators
525
                                        assert(false); // This cannot happen because jwtSecurityCheck will check for unknown generators
423
                                        break;
526
                                        break;
Line 436... Line 539...
436
                if (is_null(self::getActiveProvider())) {
539
                if (is_null(self::getActiveProvider())) {
437
                        $this->adminLogin();
540
                        $this->adminLogin();
438
                        $loginfo = 'into new JWT session';
541
                        $loginfo = 'into new JWT session';
439
                        self::$contentProvider = $this;
542
                        self::$contentProvider = $this;
440
                } else {
543
                } else {
441
                        $gen = $this->getValue('oidplus_generator',-1);
544
                        $gen = $this->getValue(self::CLAIM_GENERATOR,-1);
442
                        switch ($gen) {
545
                        switch ($gen) {
443
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_AJAX :
546
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_AJAX :
444
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_REST :
547
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_REST :
445
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_MANUAL :
548
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_MANUAL :
446
                                        throw new OIDplusException(_L('This kind of JWT token cannot be altered. Therefore you cannot do this action.'));
549
                                        throw new OIDplusException(_L('This kind of JWT token cannot be altered. Therefore you cannot do this action.'));
447
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_LOGIN :
550
                                case OIDplusAuthContentStoreJWT::JWT_GENERATOR_LOGIN :
448
                                        if (!OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_ADMIN', true)) {
551
                                        if (!OIDplus::baseConfig()->getValue('JWT_ALLOW_LOGIN_ADMIN', true)) {
449
                                                throw new OIDplusException(_L('You cannot add this login credential to your existing "remember me" session. You need to log-out first.'));
552
                                                throw new OIDplusException(_L('The administrator has disabled this feature. (Base configuration setting %1).','JWT_ALLOW_LOGIN_ADMIN'));
450
                                        }
553
                                        }
451
                                        break;
554
                                        break;
452
                                default:
555
                                default:
453
                                        assert(false); // This cannot happen because jwtSecurityCheck will check for unknown generators
556
                                        assert(false); // This cannot happen because jwtSecurityCheck will check for unknown generators
454
                                        break;
557
                                        break;
Line 484... Line 587...
484
         * @return string
587
         * @return string
485
         * @throws OIDplusException
588
         * @throws OIDplusException
486
         */
589
         */
487
        public function getJWTToken(): string {
590
        public function getJWTToken(): string {
488
                $payload = $this->content;
591
                $payload = $this->content;
489
                $payload["oidplus_ssh"] = self::getSsh(); // SSH = Server Secret Hash
592
                $payload[self::CLAIM_SSH] = self::getSsh(); // SSH = Server Secret Hash
490
                $payload["iss"] = OIDplus::getEditionInfo()['jwtaud'];
593
                $payload["iss"] = OIDplus::getEditionInfo()['jwtaud'];
491
                $payload["aud"] = OIDplus::getEditionInfo()['jwtaud'];
594
                $payload["aud"] = OIDplus::getEditionInfo()['jwtaud'];
492
                $payload["jti"] = gen_uuid();
595
                $payload["jti"] = gen_uuid();
493
                $payload["iat"] = time();
596
                $payload["iat"] = time();
494
 
597