Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the encrypted payload from AuthCode and RefreshToken #1470

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
77fd3e6
Remove the encrypted payload from AuthCode and RefreshToken
craigp1231 Jan 19, 2025
0667f32
Satisfy tests for Auth Code And Refresh Token
craigp1231 Jan 19, 2025
c7c6434
Syntax fixes
craigp1231 Jan 20, 2025
592b964
getRefreshTokenEntity should return RefreshTokenEntityInterface
craigp1231 Feb 1, 2025
411e795
Exception should be thrown if RefreshTokenEntity is null
craigp1231 Feb 1, 2025
3612121
Removing Encryption from RefreshToken and AuthCode
craigp1231 Feb 2, 2025
8efcf6d
Satisify some tests
craigp1231 Feb 2, 2025
a0d572f
Remove Private Key from Auth Server, only needed in Access Token
craigp1231 Feb 2, 2025
c858c40
Remove null
craigp1231 Feb 2, 2025
5e0f156
getDeviceCodeEntityByUserCode
craigp1231 Feb 2, 2025
5ed7d0a
set private key on Access Token Repo
craigp1231 Feb 2, 2025
fd16e69
Throw exceptions if device code has expired or revoked
craigp1231 Feb 2, 2025
6c3d1a0
Add different signer ability
craigp1231 Feb 3, 2025
236654e
Fixing Device Code test
craigp1231 Feb 3, 2025
dd3f880
Fix scope entity problem
craigp1231 Feb 3, 2025
d0e20e3
Whoops
craigp1231 Feb 3, 2025
82f114f
Fix return declarations @ example
xerc Jan 25, 2025
73d9cf4
always validate the client
hafezdivandari Jun 30, 2024
da0214d
pass grant type to getClientEntity
hafezdivandari Jun 30, 2024
102b871
fix tests
hafezdivandari Aug 29, 2024
bd87994
add ClientEntityInterface::hasGrantType()
hafezdivandari Oct 1, 2024
3c8f14e
use unauthorized_client error
hafezdivandari Oct 4, 2024
90dd8db
validate confidential clients
hafezdivandari Oct 18, 2024
b2114f4
require client_secret for confidential clients
hafezdivandari Oct 22, 2024
dfef82f
redirect uri is required on auth code
hafezdivandari Nov 9, 2024
04ecd81
fix tests
hafezdivandari Nov 9, 2024
839aa7d
fix tests
hafezdivandari Nov 19, 2024
0d6239c
bypass bc breaking change and add tests
hafezdivandari Dec 4, 2024
50120e9
formatting
hafezdivandari Dec 4, 2024
7a6ea34
Update changelog
Sephster Feb 6, 2025
c64e2fe
Remove the encrypted payload from AuthCode and RefreshToken
craigp1231 Jan 19, 2025
efa3a61
Satisfy tests for Auth Code And Refresh Token
craigp1231 Jan 19, 2025
7c7a047
Syntax fixes
craigp1231 Jan 20, 2025
53078b2
Removing Encryption from RefreshToken and AuthCode
craigp1231 Feb 2, 2025
6410100
Satisify some tests
craigp1231 Feb 2, 2025
fc1116e
Fix tests
craigp1231 Feb 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Added a new function to the provided ClientTrait, `supportsGrantType` to allow the auth server to issue the response `unauthorized_client` when applicable (PR #1420)

### Fixed
- Clients only validated for Refresh, Device Code, and Password grants if the client is confidential (PR #1420)

### Changed
- Key permission checks ignored on Windows regardless of userland choice as cannot be run successfully on this OS (PR #1447)

Expand Down
7 changes: 3 additions & 4 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# Example implementations
# Example implementations (via [`Slim 3`](https://github.com/slimphp/Slim/tree/3.x))

## Installation

0. Run `composer install` in this directory to install dependencies
0. Create a private key `openssl genrsa -out private.key 2048`
0. Create a public key `openssl rsa -in private.key -pubout > public.key`
0. `cd` into the public directory
0. Start a PHP server `php -S localhost:4444`
0. Export the public key `openssl rsa -in private.key -pubout > public.key`
0. Start local PHP server `php -S 127.0.0.1:4444 -t public/`

## Testing the client credentials grant example

Expand Down
8 changes: 3 additions & 5 deletions examples/src/Repositories/AccessTokenRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Entities\UserEntityInterface;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use OAuth2ServerExamples\Entities\AccessTokenEntity;

Expand Down Expand Up @@ -46,20 +47,17 @@ public function isAccessTokenRevoked($tokenId): bool
/**
* {@inheritdoc}
*/
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null): AccessTokenEntityInterface
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, ?UserEntityInterface $user = null): AccessTokenEntityInterface
{
$accessToken = new AccessTokenEntity();

$accessToken->setClient($clientEntity);
$accessToken->setUser($user);

foreach ($scopes as $scope) {
$accessToken->addScope($scope);
}

if ($userIdentifier !== null) {
$accessToken->setUserIdentifier((string) $userIdentifier);
}

return $accessToken;
}
}
8 changes: 4 additions & 4 deletions examples/src/Repositories/AuthCodeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,31 @@ class AuthCodeRepository implements AuthCodeRepositoryInterface
/**
* {@inheritdoc}
*/
public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity)
public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity): void
{
// Some logic to persist the auth code to a database
}

/**
* {@inheritdoc}
*/
public function revokeAuthCode($codeId)
public function revokeAuthCode($codeId): void
{
// Some logic to revoke the auth code in a database
}

/**
* {@inheritdoc}
*/
public function isAuthCodeRevoked($codeId)
public function isAuthCodeRevoked($codeId): bool
{
return false; // The auth code has not been revoked
}

/**
* {@inheritdoc}
*/
public function getNewAuthCode()
public function getNewAuthCode(): AuthCodeEntityInterface
{
return new AuthCodeEntity();
}
Expand Down
32 changes: 4 additions & 28 deletions src/AuthorizationServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use DateInterval;
use Defuse\Crypto\Key;
use League\OAuth2\Server\Entities\UserEntityInterface;
use League\OAuth2\Server\EventEmitting\EmitterAwareInterface;
use League\OAuth2\Server\EventEmitting\EmitterAwarePolyfill;
use League\OAuth2\Server\Exception\OAuthServerException;
Expand Down Expand Up @@ -42,14 +43,8 @@ class AuthorizationServer implements EmitterAwareInterface
*/
protected array $grantTypeAccessTokenTTL = [];

protected CryptKeyInterface $privateKey;

protected CryptKeyInterface $publicKey;

protected ResponseTypeInterface $responseType;

private string|Key $encryptionKey;

private string $defaultScope = '';

private bool $revokeRefreshTokens = true;
Expand All @@ -61,17 +56,8 @@ public function __construct(
private ClientRepositoryInterface $clientRepository,
private AccessTokenRepositoryInterface $accessTokenRepository,
private ScopeRepositoryInterface $scopeRepository,
CryptKeyInterface|string $privateKey,
Key|string $encryptionKey,
ResponseTypeInterface|null $responseType = null
) {
if ($privateKey instanceof CryptKeyInterface === false) {
$privateKey = new CryptKey($privateKey);
}

$this->privateKey = $privateKey;
$this->encryptionKey = $encryptionKey;

if ($responseType === null) {
$responseType = new BearerTokenResponse();
} else {
Expand All @@ -94,9 +80,7 @@ public function enableGrantType(GrantTypeInterface $grantType, DateInterval|null
$grantType->setClientRepository($this->clientRepository);
$grantType->setScopeRepository($this->scopeRepository);
$grantType->setDefaultScope($this->defaultScope);
$grantType->setPrivateKey($this->privateKey);
$grantType->setEmitter($this->getEmitter());
$grantType->setEncryptionKey($this->encryptionKey);
$grantType->revokeRefreshTokens($this->revokeRefreshTokens);

$this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
Expand Down Expand Up @@ -152,10 +136,10 @@ public function respondToDeviceAuthorizationRequest(ServerRequestInterface $requ
/**
* Complete a device authorization request
*/
public function completeDeviceAuthorizationRequest(string $deviceCode, string $userId, bool $userApproved): void
public function completeDeviceAuthorizationRequest(string $deviceCode, UserEntityInterface $user, bool $userApproved): void
{
$this->enabledGrantTypes['urn:ietf:params:oauth:grant-type:device_code']
->completeDeviceAuthorizationRequest($deviceCode, $userId, $userApproved);
->completeDeviceAuthorizationRequest($deviceCode, $user, $userApproved);
}

/**
Expand Down Expand Up @@ -187,15 +171,7 @@ public function respondToAccessTokenRequest(ServerRequestInterface $request, Res
*/
protected function getResponseType(): ResponseTypeInterface
{
$responseType = clone $this->responseType;

if ($responseType instanceof AbstractResponseType) {
$responseType->setPrivateKey($this->privateKey);
}

$responseType->setEncryptionKey($this->encryptionKey);

return $responseType;
return clone $this->responseType;
}

/**
Expand Down
2 changes: 0 additions & 2 deletions src/AuthorizationValidators/BearerTokenValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@

class BearerTokenValidator implements AuthorizationValidatorInterface
{
use CryptTrait;

protected CryptKeyInterface $publicKey;

private Configuration $jwtConfiguration;
Expand Down
90 changes: 0 additions & 90 deletions src/CryptTrait.php

This file was deleted.

13 changes: 9 additions & 4 deletions src/Entities/AccessTokenEntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@
interface AccessTokenEntityInterface extends TokenInterface
{
/**
* Set a private key used to encrypt the access token.
* Generate a string representation of the access token.
*/
public function setPrivateKey(CryptKeyInterface $privateKey): void;
public function toString(): string;

/**
* Generate a string representation of the access token.
* Set the algorithm for signing the access token with the given private key
*
* @see https://lcobucci-jwt.readthedocs.io/en/latest/supported-algorithms/
*
* Symmetric - HS256, HS384, HS512, BLAKE2B
* Asymmetric - ES256, ES384, ES512, RS256, RS384, RS512, EdDSA
*/
public function toString(): string;
public function setSigner(string $signerAlgorithm, CryptKeyInterface $privateKey): void;
}
12 changes: 10 additions & 2 deletions src/Entities/AuthCodeEntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@

interface AuthCodeEntityInterface extends TokenInterface
{
public function getRedirectUri(): string|null;
public function getRedirectUri(): ?string;

public function setRedirectUri(string $uri): void;
public function setRedirectUri(?string $uri): void;

public function setCodeChallenge(?string $codeChallenge): void;

public function getCodeChallenge(): ?string;

public function setCodeChallengeMethod(?string $codeChallengeMethod): void;

public function getCodeChallengeMethod(): ?string;
}
7 changes: 7 additions & 0 deletions src/Entities/ClientEntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@ public function getRedirectUri(): string|array;
* Returns true if the client is confidential.
*/
public function isConfidential(): bool;

/*
* Returns true if the client supports the given grant type.
*
* To be added in a future major release.
*/
// public function supportsGrantType(string $grantType): bool;
}
28 changes: 1 addition & 27 deletions src/Entities/RefreshTokenEntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,8 @@

namespace League\OAuth2\Server\Entities;

use DateTimeImmutable;

interface RefreshTokenEntityInterface
interface RefreshTokenEntityInterface extends TokenInterface
{
/**
* Get the token's identifier.
*
* @return non-empty-string
*/
public function getIdentifier(): string;

/**
* Set the token's identifier.
*
* @param non-empty-string $identifier
*/
public function setIdentifier(string $identifier): void;

/**
* Get the token's expiry date time.
*/
public function getExpiryDateTime(): DateTimeImmutable;

/**
* Set the date time when the token expires.
*/
public function setExpiryDateTime(DateTimeImmutable $dateTime): void;

/**
* Set the access token that the refresh token was associated with.
*/
Expand Down
Loading