-
Notifications
You must be signed in to change notification settings - Fork 2
/
OIDCToken.php
124 lines (93 loc) · 3.49 KB
/
OIDCToken.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
namespace IdnoPlugins\OAuth2;
use Idno\Core\TokenProvider;
use Idno\Core\Webservice;
use Firebase\JWT\JWT;
class OIDCToken {
// JWT Token leeway
private static $leeway = 10;
/**
* When given a token, generate an OIDC token from it
* @param \IdnoPlugins\OAuth2\Token $token
* @return array
*/
public static function generate(Token $token) : array {
$nonce = new TokenProvider();
$application = Application::getOne(['key' => $token->key]);
if (empty($application)) {
throw new OAuth2Exception(\Idno\Core\Idno::site()->language()->_("The Application for this token could not be found"));
}
$oidc = [
'iss' => $application->getURL(), // Issuer site
'sub' => "" . $token->getOwner()->getID(), // Return the SUBJECT id
'aud' => $token->key, // Audience (client ID)
'exp' => time() + $token->expires_in, // Expires in
'iat' => time(), // Issue time
'nonce' => $nonce->generateHexToken(4), // Add a nonce
];
// Have we asked for email address?
if (strpos($token->scope, 'email') !== false) {
$oidc['email'] = $token->getOwner()->email;
}
// Add some profile information if asked for
if (strpos($token->scope, 'profile') !== false) {
$oidc['preferred_username'] = $token->getOwner()->getHandle();
$oidc['name'] = $token->getOwner()->getName();
$oidc['picture'] = $token->getOwner()->getIcon();
$oidc['profile'] = $token->getOwner()->getURL();
if ($tz = $token->getOwner()->getTimezone()) {
$oidc['zoneinfo'] = $tz;
}
}
return $oidc;
}
/**
* Decode a JWT into a usable object.
* @param string $token
* @param string $publickey
* @return object|null
*/
public static function decode(string $token, string $publickey) : ? object {
list($header, $payload, $signature) = explode(".", $token);
$plainHeader = Webservice::base64UrlDecode($header);
$jsonHeader = json_decode($plainHeader, true);
$algo = ['RS256', $jsonHeader['alg']];
JWT::$leeway = self::$leeway;
$result = JWT::decode($token, $publickey, array_unique($algo));
if ($result) {
return $result;
}
return null;
}
/**
* Decode the JWT payload WITHOUT verifying the signature.
* @param string $token
* @return object|null
*/
public static function decodeNoVerify(string $token) : ? object {
list($header, $payload, $signature) = explode(".", $token);
$decoded = json_decode(Webservice::base64UrlDecode($payload));
if ($decoded) {
return $decoded;
}
return null;
}
/**
* Is the token a JWT?
* @param string $token
* @return bool
*/
public static function isJWT(string $token) : bool {
list($header, $payload, $signature) = explode(".", $token);
if (empty($header) || !json_decode(Webservice::base64UrlDecode($header))) {
return false;
}
if (empty($payload) || !json_decode(Webservice::base64UrlDecode($payload))) {
return false;
}
if (empty($signature)) {
return false;
}
return true;
}
}