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 OAuth2\ResponseType;
use OAuth2\Encryption\EncryptionInterface;
use OAuth2\Encryption\Jwt;
use OAuth2\Storage\AccessTokenInterface as AccessTokenStorageInterface;
use OAuth2\Storage\RefreshTokenInterface;
use OAuth2\Storage\PublicKeyInterface;
use OAuth2\Storage\Memory;
/**
*
* @author Brent Shaffer <bshafs at gmail dot com>
*/
class JwtAccessToken extends AccessToken
{
protected $publicKeyStorage;
protected $encryptionUtil;
/**
* @param $config
* - store_encrypted_token_string (bool true)
* whether the entire encrypted string is stored,
* or just the token ID is stored
*/
public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
{
$this->publicKeyStorage = $publicKeyStorage;
$config = array_merge(array(
'store_encrypted_token_string' => true,
'issuer' => ''
), $config);
if (is_null($tokenStorage)) {
// a pass-thru, so we can call the parent constructor
$tokenStorage = new Memory();
}
if (is_null($encryptionUtil)) {
$encryptionUtil = new Jwt();
}
$this->encryptionUtil = $encryptionUtil;
parent::__construct($tokenStorage, $refreshStorage, $config);
}
/**
* Handle the creation of access token, also issue refresh token if supported / desirable.
*
* @param $client_id
* Client identifier related to the access token.
* @param $user_id
* User ID associated with the access token
* @param $scope
* (optional) Scopes to be stored in space-separated string.
* @param bool $includeRefreshToken
* If true, a new refresh_token will be added to the response
*
* @see http://tools.ietf.org/html/rfc6749#section-5
* @ingroup oauth2_section_5
*/
public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
{
// token to encrypt
$expires = time() + $this->config['access_lifetime'];
$id = $this->generateAccessToken();
$jwtAccessToken = array(
'id' => $id, // for BC (see #591)
'jti' => $id,
'iss' => $this->config['issuer'],
'aud' => $client_id,
'sub' => $user_id,
'exp' => $expires,
'iat' => time(),
'token_type' => $this->config['token_type'],
'scope' => $scope
);
/*
* Encode the token data into a single access_token string
*/
$access_token = $this->encodeToken($jwtAccessToken, $client_id);
/*
* Save the token to a secondary storage. This is implemented on the
* OAuth2\Storage\JwtAccessToken side, and will not actually store anything,
* if no secondary storage has been supplied
*/
$token_to_store = $this->config['store_encrypted_token_string'] ? $access_token : $jwtAccessToken['id'];
$this->tokenStorage->setAccessToken($token_to_store, $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
// token to return to the client
$token = array(
'access_token' => $access_token,
'expires_in' => $this->config['access_lifetime'],
'token_type' => $this->config['token_type'],
'scope' => $scope
);
/*
* Issue a refresh token also, if we support them
*
* Refresh Tokens are considered supported if an instance of OAuth2\Storage\RefreshTokenInterface
* is supplied in the constructor
*/
if ($includeRefreshToken && $this->refreshStorage) {
$refresh_token = $this->generateRefreshToken();
$expires = 0;
if ($this->config['refresh_token_lifetime'] > 0) {
$expires = time() + $this->config['refresh_token_lifetime'];
}
$this->refreshStorage->setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope);
$token['refresh_token'] = $refresh_token;
}
return $token;
}
protected function encodeToken(array $token, $client_id = null)
{
$private_key = $this->publicKeyStorage->getPrivateKey($client_id);
$algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
return $this->encryptionUtil->encode($token, $private_key, $algorithm);
}
}
|