JwtAccessToken.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. namespace OAuth2\ResponseType;
  3. use OAuth2\Encryption\EncryptionInterface;
  4. use OAuth2\Encryption\Jwt;
  5. use OAuth2\Storage\AccessTokenInterface as AccessTokenStorageInterface;
  6. use OAuth2\Storage\RefreshTokenInterface;
  7. use OAuth2\Storage\PublicKeyInterface;
  8. use OAuth2\Storage\Memory;
  9. /**
  10. *
  11. * @author Brent Shaffer <bshafs at gmail dot com>
  12. */
  13. class JwtAccessToken extends AccessToken
  14. {
  15. protected $publicKeyStorage;
  16. protected $encryptionUtil;
  17. /**
  18. * @param $config
  19. * - store_encrypted_token_string (bool true)
  20. * whether the entire encrypted string is stored,
  21. * or just the token ID is stored
  22. */
  23. public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
  24. {
  25. $this->publicKeyStorage = $publicKeyStorage;
  26. $config = array_merge(array(
  27. 'store_encrypted_token_string' => true,
  28. 'issuer' => ''
  29. ), $config);
  30. if (is_null($tokenStorage)) {
  31. // a pass-thru, so we can call the parent constructor
  32. $tokenStorage = new Memory();
  33. }
  34. if (is_null($encryptionUtil)) {
  35. $encryptionUtil = new Jwt();
  36. }
  37. $this->encryptionUtil = $encryptionUtil;
  38. parent::__construct($tokenStorage, $refreshStorage, $config);
  39. }
  40. /**
  41. * Handle the creation of access token, also issue refresh token if supported / desirable.
  42. *
  43. * @param $client_id
  44. * Client identifier related to the access token.
  45. * @param $user_id
  46. * User ID associated with the access token
  47. * @param $scope
  48. * (optional) Scopes to be stored in space-separated string.
  49. * @param bool $includeRefreshToken
  50. * If true, a new refresh_token will be added to the response
  51. *
  52. * @see http://tools.ietf.org/html/rfc6749#section-5
  53. * @ingroup oauth2_section_5
  54. */
  55. public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
  56. {
  57. // token to encrypt
  58. $expires = time() + $this->config['access_lifetime'];
  59. $id = $this->generateAccessToken();
  60. $jwtAccessToken = array(
  61. 'id' => $id, // for BC (see #591)
  62. 'jti' => $id,
  63. 'iss' => $this->config['issuer'],
  64. 'aud' => $client_id,
  65. 'sub' => $user_id,
  66. 'exp' => $expires,
  67. 'iat' => time(),
  68. 'token_type' => $this->config['token_type'],
  69. 'scope' => $scope
  70. );
  71. /*
  72. * Encode the token data into a single access_token string
  73. */
  74. $access_token = $this->encodeToken($jwtAccessToken, $client_id);
  75. /*
  76. * Save the token to a secondary storage. This is implemented on the
  77. * OAuth2\Storage\JwtAccessToken side, and will not actually store anything,
  78. * if no secondary storage has been supplied
  79. */
  80. $token_to_store = $this->config['store_encrypted_token_string'] ? $access_token : $jwtAccessToken['id'];
  81. $this->tokenStorage->setAccessToken($token_to_store, $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
  82. // token to return to the client
  83. $token = array(
  84. 'access_token' => $access_token,
  85. 'expires_in' => $this->config['access_lifetime'],
  86. 'token_type' => $this->config['token_type'],
  87. 'scope' => $scope
  88. );
  89. /*
  90. * Issue a refresh token also, if we support them
  91. *
  92. * Refresh Tokens are considered supported if an instance of OAuth2\Storage\RefreshTokenInterface
  93. * is supplied in the constructor
  94. */
  95. if ($includeRefreshToken && $this->refreshStorage) {
  96. $refresh_token = $this->generateRefreshToken();
  97. $expires = 0;
  98. if ($this->config['refresh_token_lifetime'] > 0) {
  99. $expires = time() + $this->config['refresh_token_lifetime'];
  100. }
  101. $this->refreshStorage->setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope);
  102. $token['refresh_token'] = $refresh_token;
  103. }
  104. return $token;
  105. }
  106. protected function encodeToken(array $token, $client_id = null)
  107. {
  108. $private_key = $this->publicKeyStorage->getPrivateKey($client_id);
  109. $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
  110. return $this->encryptionUtil->encode($token, $private_key, $algorithm);
  111. }
  112. }