mirror of
https://github.com/elyby/oauth2-server.git
synced 2024-11-23 05:33:06 +05:30
Merge pull request #874 from lookyman/access-token-jwt
Generalized access token format
This commit is contained in:
commit
ca6be0577c
@ -30,3 +30,4 @@ after_script:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- 8.0.0
|
||||
|
@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- Replace `convertToJWT()` interface with a more generic `__toString()` to improve extensibility (PR #874)
|
||||
- The `invalidClient()` function accepts a PSR-7 compliant `$serverRequest` argument to avoid accessing the `$_SERVER` global variable and improve testing (PR #899)
|
||||
|
||||
## [7.1.1] - released 2018-05-21
|
||||
|
@ -9,17 +9,17 @@
|
||||
|
||||
namespace League\OAuth2\Server\Entities;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
|
||||
interface AccessTokenEntityInterface extends TokenInterface
|
||||
{
|
||||
/**
|
||||
* Generate a JWT from the access token
|
||||
*
|
||||
* @param CryptKey $privateKey
|
||||
*
|
||||
* @return Token
|
||||
* Set a private key used to encrypt the access token.
|
||||
*/
|
||||
public function convertToJWT(CryptKey $privateKey);
|
||||
public function setPrivateKey(CryptKey $privateKey);
|
||||
|
||||
/**
|
||||
* Generate a string representation of the access token.
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
||||
|
@ -19,6 +19,19 @@ use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||
|
||||
trait AccessTokenTrait
|
||||
{
|
||||
/**
|
||||
* @var CryptKey
|
||||
*/
|
||||
private $privateKey;
|
||||
|
||||
/**
|
||||
* Set the private key used to encrypt this access token.
|
||||
*/
|
||||
public function setPrivateKey(CryptKey $privateKey)
|
||||
{
|
||||
$this->privateKey = $privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JWT from the access token
|
||||
*
|
||||
@ -26,7 +39,7 @@ trait AccessTokenTrait
|
||||
*
|
||||
* @return Token
|
||||
*/
|
||||
public function convertToJWT(CryptKey $privateKey)
|
||||
private function convertToJWT(CryptKey $privateKey)
|
||||
{
|
||||
return (new Builder())
|
||||
->setAudience($this->getClient()->getIdentifier())
|
||||
@ -40,6 +53,14 @@ trait AccessTokenTrait
|
||||
->getToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a string representation from the access token
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->convertToJWT($this->privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClientEntityInterface
|
||||
*/
|
||||
|
@ -361,6 +361,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setUserIdentifier($userIdentifier);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add($accessTokenTTL));
|
||||
$accessToken->setPrivateKey($this->privateKey);
|
||||
|
||||
foreach ($scopes as $scope) {
|
||||
$accessToken->addScope($scope);
|
||||
|
@ -216,7 +216,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
||||
$this->makeRedirectUri(
|
||||
$finalRedirectUri,
|
||||
[
|
||||
'access_token' => (string) $accessToken->convertToJWT($this->privateKey),
|
||||
'access_token' => (string) $accessToken,
|
||||
'token_type' => 'Bearer',
|
||||
'expires_in' => $accessToken->getExpiryDateTime()->getTimestamp() - (new \DateTime())->getTimestamp(),
|
||||
'state' => $authorizationRequest->getState(),
|
||||
|
@ -24,12 +24,10 @@ class BearerTokenResponse extends AbstractResponseType
|
||||
{
|
||||
$expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp();
|
||||
|
||||
$jwtAccessToken = $this->accessToken->convertToJWT($this->privateKey);
|
||||
|
||||
$responseParams = [
|
||||
'token_type' => 'Bearer',
|
||||
'expires_in' => $expireDateTime - (new \DateTime())->getTimestamp(),
|
||||
'access_token' => (string) $jwtAccessToken,
|
||||
'access_token' => (string) $this->accessToken,
|
||||
];
|
||||
|
||||
if ($this->refreshToken instanceof RefreshTokenEntityInterface) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\Event\Emitter;
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
@ -353,6 +354,7 @@ class AbstractGrantTest extends TestCase
|
||||
|
||||
/** @var AbstractGrant $grantMock */
|
||||
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
|
||||
$grantMock->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$grantMock->setAccessTokenRepository($accessTokenRepoMock);
|
||||
|
||||
$abstractGrantReflection = new \ReflectionClass($grantMock);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
@ -40,7 +41,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->cryptStub = new CryptTraitStub;
|
||||
$this->cryptStub = new CryptTraitStub();
|
||||
}
|
||||
|
||||
public function testGetIdentifier()
|
||||
@ -608,6 +609,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@ -676,6 +678,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@ -747,6 +750,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@ -1537,6 +1541,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
new \DateInterval('PT10M')
|
||||
);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest));
|
||||
}
|
||||
@ -1624,6 +1629,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@ -1695,6 +1701,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
@ -1766,6 +1773,7 @@ class AuthCodeGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setRefreshTokenRepository($refreshTokenRepositoryMock);
|
||||
$grant->setEncryptionKey($this->cryptStub->getKey());
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$request = new ServerRequest(
|
||||
[],
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
@ -44,6 +45,7 @@ class ClientCredentialsGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setDefaultScope(self::DEFAULT_SCOPE);
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$serverRequest = new ServerRequest();
|
||||
$serverRequest = $serverRequest->withParsedBody(
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace LeagueTests\Grant;
|
||||
|
||||
use League\OAuth2\Server\CryptKey;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
use League\OAuth2\Server\Grant\PasswordGrant;
|
||||
@ -60,6 +61,7 @@ class PasswordGrantTest extends TestCase
|
||||
$grant->setAccessTokenRepository($accessTokenRepositoryMock);
|
||||
$grant->setScopeRepository($scopeRepositoryMock);
|
||||
$grant->setDefaultScope(self::DEFAULT_SCOPE);
|
||||
$grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$serverRequest = new ServerRequest();
|
||||
$serverRequest = $serverRequest->withParsedBody(
|
||||
|
@ -29,8 +29,9 @@ class ResourceServerMiddlewareTest extends TestCase
|
||||
$accessToken->setUserIdentifier(123);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$token = $accessToken->convertToJWT(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$token = (string) $accessToken;
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $token));
|
||||
@ -64,8 +65,9 @@ class ResourceServerMiddlewareTest extends TestCase
|
||||
$accessToken->setUserIdentifier(123);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->sub(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$token = $accessToken->convertToJWT(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
$token = (string) $accessToken;
|
||||
|
||||
$request = new ServerRequest();
|
||||
$request = $request->withHeader('authorization', sprintf('Bearer %s', $token));
|
||||
|
@ -35,6 +35,7 @@ class BearerResponseTypeTest extends TestCase
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->addScope($scope);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$refreshToken = new RefreshTokenEntity();
|
||||
$refreshToken->setIdentifier('abcdef');
|
||||
@ -77,6 +78,7 @@ class BearerResponseTypeTest extends TestCase
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->addScope($scope);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$refreshToken = new RefreshTokenEntity();
|
||||
$refreshToken->setIdentifier('abcdef');
|
||||
@ -119,6 +121,7 @@ class BearerResponseTypeTest extends TestCase
|
||||
$accessToken->setUserIdentifier(123);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$refreshToken = new RefreshTokenEntity();
|
||||
$refreshToken->setIdentifier('abcdef');
|
||||
@ -164,6 +167,7 @@ class BearerResponseTypeTest extends TestCase
|
||||
$accessToken->setUserIdentifier(123);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$refreshToken = new RefreshTokenEntity();
|
||||
$refreshToken->setIdentifier('abcdef');
|
||||
@ -206,6 +210,7 @@ class BearerResponseTypeTest extends TestCase
|
||||
$accessToken->setUserIdentifier(123);
|
||||
$accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$accessToken->setClient($client);
|
||||
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
|
||||
|
||||
$refreshToken = new RefreshTokenEntity();
|
||||
$refreshToken->setIdentifier('abcdef');
|
||||
|
Loading…
Reference in New Issue
Block a user