From b40fd512f467368fbe143da80823f07577bd0700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Obradovi=C4=87?= Date: Wed, 26 Feb 2020 17:57:18 +0100 Subject: [PATCH 01/10] Update branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4957c30e..4ef3478d 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "4.x-dev" } } } From 9ec7875c1571976bc7e40ce18f2ac02f1b13448a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berislav=20Balogovi=C4=87?= Date: Wed, 18 Mar 2020 19:48:23 +0100 Subject: [PATCH 02/10] Fix casing of OAuth2AuthenticationFailedException --- EventListener/ConvertExceptionToResponseListener.php | 4 ++-- ...dException.php => OAuth2AuthenticationFailedException.php} | 2 +- Security/Firewall/OAuth2Listener.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename Security/Exception/{Oauth2AuthenticationFailedException.php => OAuth2AuthenticationFailedException.php} (84%) diff --git a/EventListener/ConvertExceptionToResponseListener.php b/EventListener/ConvertExceptionToResponseListener.php index b29fdffe..535eee16 100644 --- a/EventListener/ConvertExceptionToResponseListener.php +++ b/EventListener/ConvertExceptionToResponseListener.php @@ -7,7 +7,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Trikoder\Bundle\OAuth2Bundle\Security\Exception\InsufficientScopesException; -use Trikoder\Bundle\OAuth2Bundle\Security\Exception\Oauth2AuthenticationFailedException; +use Trikoder\Bundle\OAuth2Bundle\Security\Exception\OAuth2AuthenticationFailedException; /** * @author Tobias Nyholm @@ -17,7 +17,7 @@ final class ConvertExceptionToResponseListener public function onKernelException(ExceptionEvent $event): void { $exception = $event->getThrowable(); - if ($exception instanceof InsufficientScopesException || $exception instanceof Oauth2AuthenticationFailedException) { + if ($exception instanceof InsufficientScopesException || $exception instanceof OAuth2AuthenticationFailedException) { $event->setResponse(new Response($exception->getMessage(), $exception->getCode())); } } diff --git a/Security/Exception/Oauth2AuthenticationFailedException.php b/Security/Exception/OAuth2AuthenticationFailedException.php similarity index 84% rename from Security/Exception/Oauth2AuthenticationFailedException.php rename to Security/Exception/OAuth2AuthenticationFailedException.php index f42097ed..b21d4d09 100644 --- a/Security/Exception/Oauth2AuthenticationFailedException.php +++ b/Security/Exception/OAuth2AuthenticationFailedException.php @@ -9,7 +9,7 @@ /** * @author Tobias Nyholm */ -class Oauth2AuthenticationFailedException extends AuthenticationException +class OAuth2AuthenticationFailedException extends AuthenticationException { public static function create(string $message): self { diff --git a/Security/Firewall/OAuth2Listener.php b/Security/Firewall/OAuth2Listener.php index 618cdc51..0bf62ae3 100644 --- a/Security/Firewall/OAuth2Listener.php +++ b/Security/Firewall/OAuth2Listener.php @@ -13,7 +13,7 @@ use Trikoder\Bundle\OAuth2Bundle\Security\Authentication\Token\OAuth2Token; use Trikoder\Bundle\OAuth2Bundle\Security\Authentication\Token\OAuth2TokenFactory; use Trikoder\Bundle\OAuth2Bundle\Security\Exception\InsufficientScopesException; -use Trikoder\Bundle\OAuth2Bundle\Security\Exception\Oauth2AuthenticationFailedException; +use Trikoder\Bundle\OAuth2Bundle\Security\Exception\OAuth2AuthenticationFailedException; final class OAuth2Listener { @@ -68,7 +68,7 @@ public function __invoke(RequestEvent $event) /** @var OAuth2Token $authenticatedToken */ $authenticatedToken = $this->authenticationManager->authenticate($this->oauth2TokenFactory->createOAuth2Token($request, null, $this->providerKey)); } catch (AuthenticationException $e) { - throw Oauth2AuthenticationFailedException::create($e->getMessage()); + throw OAuth2AuthenticationFailedException::create($e->getMessage()); } if (!$this->isAccessToRouteGranted($event->getRequest(), $authenticatedToken)) { From 60e9cadef8220e3fa650dd4777a7e3f2bd904414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berislav=20Balogovi=C4=87?= Date: Mon, 5 Oct 2020 02:29:35 +0200 Subject: [PATCH 03/10] Remove deprecated config options. --- DependencyInjection/Configuration.php | 65 +----------------------- README.md | 22 --------- Tests/Unit/ExtensionTest.php | 71 +++------------------------ 3 files changed, 8 insertions(+), 150 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 707b2266..8c16b06d 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -79,48 +79,9 @@ private function createAuthorizationServerNode(): NodeDefinition ->cannotBeEmpty() ->defaultValue('P1M') ->end() - - // @TODO Remove in v4 start - - ->scalarNode('auth_code_ttl') - ->info("How long the issued authorization code should be valid for.\nThe value should be a valid interval: http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters") - ->cannotBeEmpty() - ->setDeprecated('"%path%.%node%" is deprecated, use "%path%.grant_types.authorization_code.auth_code_ttl" instead.') - ->beforeNormalization() - ->ifNull() - ->thenUnset() - ->end() - ->end() - ->booleanNode('require_code_challenge_for_public_clients') - ->info('Whether to require code challenge for public clients for the authorization code grant.') - ->setDeprecated('"%path%.%node%" is deprecated, use "%path%.grant_types.authorization_code.require_code_challenge_for_public_clients" instead.') - ->beforeNormalization() - ->ifNull() - ->thenUnset() - ->end() - ->end() ->end() ; - foreach (OAuth2Grants::ALL as $grantType => $grantTypeName) { - $oldGrantType = 'authorization_code' === $grantType ? 'auth_code' : $grantType; - - $node - ->children() - ->booleanNode(sprintf('enable_%s_grant', $oldGrantType)) - ->info(sprintf('Whether to enable the %s grant.', $grantTypeName)) - ->setDeprecated(sprintf('"%%path%%.%%node%%" is deprecated, use "%%path%%.grant_types.%s.enable" instead.', $grantType)) - ->beforeNormalization() - ->ifNull() - ->thenUnset() - ->end() - ->end() - ->end() - ; - } - - // @TODO Remove in v4 end - $node->append($this->createAuthorizationServerGrantTypesNode()); $node @@ -134,33 +95,9 @@ private function createAuthorizationServerNode(): NodeDefinition if (isset($grantTypesWithRefreshToken[$grantType])) { $grantTypeConfig['refresh_token_ttl'] = $grantTypeConfig['refresh_token_ttl'] ?? $v['refresh_token_ttl']; } - - // @TODO Remove in v4 start - $oldGrantType = 'authorization_code' === $grantType ? 'auth_code' : $grantType; - - $grantTypeConfig['enable'] = $v[sprintf('enable_%s_grant', $oldGrantType)] ?? $grantTypeConfig['enable']; - - if ('authorization_code' === $grantType) { - $grantTypeConfig['auth_code_ttl'] = $v['auth_code_ttl'] ?? $grantTypeConfig['auth_code_ttl']; - $grantTypeConfig['require_code_challenge_for_public_clients'] = $v['require_code_challenge_for_public_clients'] - ?? $grantTypeConfig['require_code_challenge_for_public_clients']; - } - // @TODO Remove in v4 end } - unset( - $v['access_token_ttl'], - $v['refresh_token_ttl'], - // @TODO Remove in v4 start - $v['enable_auth_code_grant'], - $v['enable_client_credentials_grant'], - $v['enable_implicit_grant'], - $v['enable_password_grant'], - $v['enable_refresh_token_grant'], - $v['auth_code_ttl'], - $v['require_code_challenge_for_public_clients'] - // @TODO Remove in v4 end - ); + unset($v['access_token_ttl'], $v['refresh_token_ttl']); return $v; }) diff --git a/README.md b/README.md index 63a53d83..1fc84135 100644 --- a/README.md +++ b/README.md @@ -68,28 +68,6 @@ This package is currently in the active development. # The value should be a valid interval: http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters refresh_token_ttl: P1M - # How long the issued authorization code should be valid for. - # The value should be a valid interval: http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters - auth_code_ttl: ~ # Deprecated ("trikoder_oauth2.authorization_server.auth_code_ttl" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.authorization_code.auth_code_ttl" instead.) - - # Whether to require code challenge for public clients for the authorization code grant. - require_code_challenge_for_public_clients: ~ # Deprecated ("trikoder_oauth2.authorization_server.require_code_challenge_for_public_clients" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.authorization_code.require_code_challenge_for_public_clients" instead.) - - # Whether to enable the authorization code grant. - enable_auth_code_grant: ~ # Deprecated ("trikoder_oauth2.authorization_server.enable_auth_code_grant" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.authorization_code.enable" instead.) - - # Whether to enable the client credentials grant. - enable_client_credentials_grant: ~ # Deprecated ("trikoder_oauth2.authorization_server.enable_client_credentials_grant" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.client_credentials.enable" instead.) - - # Whether to enable the implicit grant. - enable_implicit_grant: ~ # Deprecated ("trikoder_oauth2.authorization_server.enable_implicit_grant" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.implicit.enable" instead.) - - # Whether to enable the password grant. - enable_password_grant: ~ # Deprecated ("trikoder_oauth2.authorization_server.enable_password_grant" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.password.enable" instead.) - - # Whether to enable the refresh token grant. - enable_refresh_token_grant: ~ # Deprecated ("trikoder_oauth2.authorization_server.enable_refresh_token_grant" is deprecated, use "trikoder_oauth2.authorization_server.grant_types.refresh_token.enable" instead.) - # Enable and configure grant types. grant_types: authorization_code: diff --git a/Tests/Unit/ExtensionTest.php b/Tests/Unit/ExtensionTest.php index 146ae35f..3ed16159 100644 --- a/Tests/Unit/ExtensionTest.php +++ b/Tests/Unit/ExtensionTest.php @@ -265,44 +265,12 @@ public function grantsProvider(): iterable yield 'Refresh token grant can be disabled' => [ RefreshTokenGrant::class, 'refresh_token.enable', false, ]; - - yield 'Legacy authorization code grant can be enabled' => [ - AuthCodeGrant::class, 'enable_auth_code_grant', true, - ]; - yield 'Legacy authorization code grant can be disabled' => [ - AuthCodeGrant::class, 'enable_auth_code_grant', false, - ]; - yield 'Legacy client credentials grant can be enabled' => [ - ClientCredentialsGrant::class, 'enable_client_credentials_grant', true, - ]; - yield 'Legacy client credentials grant can be disabled' => [ - ClientCredentialsGrant::class, 'enable_client_credentials_grant', false, - ]; - yield 'Legacy implicit grant can be enabled' => [ - ImplicitGrant::class, 'enable_implicit_grant', true, - ]; - yield 'Legacy implicit grant can be disabled' => [ - ImplicitGrant::class, 'enable_implicit_grant', false, - ]; - yield 'Legacy password grant can be enabled' => [ - PasswordGrant::class, 'enable_password_grant', true, - ]; - yield 'Legacy password grant can be disabled' => [ - PasswordGrant::class, 'enable_password_grant', false, - ]; - yield 'Legacy refresh token grant can be enabled' => [ - RefreshTokenGrant::class, 'enable_refresh_token_grant', true, - ]; - yield 'Legacy refresh token grant can be disabled' => [ - RefreshTokenGrant::class, 'enable_refresh_token_grant', false, - ]; } /** * @dataProvider requireCodeChallengeForPublicClientsProvider */ public function testAuthCodeGrantDisableRequireCodeChallengeForPublicClientsConfig( - string $configKey, ?bool $requireCodeChallengeForPublicClients, bool $shouldTheRequirementBeDisabled ): void { @@ -313,7 +281,7 @@ public function testAuthCodeGrantDisableRequireCodeChallengeForPublicClientsConf $extension = new TrikoderOAuth2Extension(); $configuration = $this->getValidConfiguration([ - $configKey => $requireCodeChallengeForPublicClients, + 'authorization_code.require_code_challenge_for_public_clients' => $requireCodeChallengeForPublicClients, ]); $extension->load($configuration, $container); @@ -336,23 +304,13 @@ public function testAuthCodeGrantDisableRequireCodeChallengeForPublicClientsConf public function requireCodeChallengeForPublicClientsProvider(): iterable { yield 'When not requiring code challenge for public clients the requirement should be disabled' => [ - 'authorization_code.require_code_challenge_for_public_clients', false, true, + false, true, ]; yield 'When code challenge for public clients is required the requirement should not be disabled' => [ - 'authorization_code.require_code_challenge_for_public_clients', true, false, + true, false, ]; yield 'With the default value the requirement should not be disabled' => [ - 'authorization_code.require_code_challenge_for_public_clients', null, false, - ]; - - yield 'Legacy when not requiring code challenge for public clients the requirement should be disabled' => [ - 'require_code_challenge_for_public_clients', false, true, - ]; - yield 'Legacy when code challenge for public clients is required the requirement should not be disabled' => [ - 'require_code_challenge_for_public_clients', true, false, - ]; - yield 'Legacy with the default value the requirement should not be disabled' => [ - 'require_code_challenge_for_public_clients', null, false, + null, false, ]; } @@ -360,7 +318,6 @@ public function requireCodeChallengeForPublicClientsProvider(): iterable * @dataProvider authCodeTTLProvider */ public function testAuthCodeTTLConfig( - string $configKey, ?string $authCodeTTL, string $expectedAuthCodeTTL ): void { @@ -371,7 +328,7 @@ public function testAuthCodeTTLConfig( $extension = new TrikoderOAuth2Extension(); $configuration = $this->getValidConfiguration([ - $configKey => $authCodeTTL, + 'authorization_code.auth_code_ttl' => $authCodeTTL, ]); $extension->load($configuration, $container); @@ -384,17 +341,10 @@ public function testAuthCodeTTLConfig( public function authCodeTTLProvider(): iterable { yield 'Authorization code TTL can be set' => [ - 'authorization_code.auth_code_ttl', 'PT20M', 'PT20M', + 'PT20M', 'PT20M', ]; yield 'When no authorization code TTL is set, the default is used' => [ - 'authorization_code.auth_code_ttl', null, 'PT10M', - ]; - - yield 'Legacy authorization code TTL can be set' => [ - 'auth_code_ttl', 'PT20M', 'PT20M', - ]; - yield 'Legacy when no authorization code TTL is set, the default is used' => [ - 'auth_code_ttl', null, 'PT10M', + null, 'PT10M', ]; } @@ -405,15 +355,8 @@ private function getValidConfiguration(array $options = []): array 'authorization_server' => [ 'private_key' => 'foo', 'encryption_key' => 'foo', - 'enable_auth_code_grant' => $options['enable_auth_code_grant'] ?? null, 'access_token_ttl' => $options['access_token_ttl'] ?? 'PT1H', 'refresh_token_ttl' => $options['refresh_token_ttl'] ?? 'P1M', - 'enable_client_credentials_grant' => $options['enable_client_credentials_grant'] ?? null, - 'enable_implicit_grant' => $options['enable_implicit_grant'] ?? null, - 'enable_password_grant' => $options['enable_password_grant'] ?? null, - 'enable_refresh_token_grant' => $options['enable_refresh_token_grant'] ?? null, - 'require_code_challenge_for_public_clients' => $options['require_code_challenge_for_public_clients'] ?? null, - 'auth_code_ttl' => $options['auth_code_ttl'] ?? null, 'grant_types' => [ 'authorization_code' => [ 'enable' => $options['authorization_code.enable'] ?? true, From 3710d33cfbd9625d936dc88ba4d065e9dc026be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berislav=20Balogovi=C4=87?= Date: Mon, 5 Oct 2020 02:29:51 +0200 Subject: [PATCH 04/10] Remove deprecated OAuth2Grants::has method. --- OAuth2Grants.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/OAuth2Grants.php b/OAuth2Grants.php index d823f17e..025a617e 100644 --- a/OAuth2Grants.php +++ b/OAuth2Grants.php @@ -54,14 +54,4 @@ final class OAuth2Grants self::PASSWORD => 'password', self::REFRESH_TOKEN => 'refresh token', ]; - - /** - * @deprecated Will be removed in v4, use {@see OAuth2Grants::ALL} instead - * - * @TODO Remove in v4. - */ - public static function has(string $grant): bool - { - return isset(self::ALL[$grant]); - } } From 9701bd5ba70eecf0fa90e5ae67d947e0c23608bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berislav=20Balogovi=C4=87?= Date: Mon, 5 Oct 2020 02:33:47 +0200 Subject: [PATCH 05/10] Add previous argument to OAuth2AuthenticationFailedException::create method --- Security/Exception/OAuth2AuthenticationFailedException.php | 5 +++-- Security/Firewall/OAuth2Listener.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Security/Exception/OAuth2AuthenticationFailedException.php b/Security/Exception/OAuth2AuthenticationFailedException.php index b21d4d09..35d8fd20 100644 --- a/Security/Exception/OAuth2AuthenticationFailedException.php +++ b/Security/Exception/OAuth2AuthenticationFailedException.php @@ -5,14 +5,15 @@ namespace Trikoder\Bundle\OAuth2Bundle\Security\Exception; use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Throwable; /** * @author Tobias Nyholm */ class OAuth2AuthenticationFailedException extends AuthenticationException { - public static function create(string $message): self + public static function create(string $message, ?Throwable $previous = null): self { - return new self($message, 401); + return new self($message, 401, $previous); } } diff --git a/Security/Firewall/OAuth2Listener.php b/Security/Firewall/OAuth2Listener.php index 817c3a43..8f1ae8a6 100644 --- a/Security/Firewall/OAuth2Listener.php +++ b/Security/Firewall/OAuth2Listener.php @@ -68,7 +68,7 @@ public function __invoke(RequestEvent $event) /** @var OAuth2Token $authenticatedToken */ $authenticatedToken = $this->authenticationManager->authenticate($this->oauth2TokenFactory->createOAuth2Token($request, null, $this->providerKey)); } catch (AuthenticationException $e) { - throw new OAuth2AuthenticationFailedException($e->getMessage(), 401, $e); + throw OAuth2AuthenticationFailedException::create($e->getMessage(), $e); } if (!$this->isAccessToRouteGranted($event->getRequest(), $authenticatedToken)) { From 3297cd76abb172285af24ebea028352f5902341e Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Tue, 24 Nov 2020 19:51:16 +0100 Subject: [PATCH 06/10] ADD: EventDispatcher in Firewall --- Resources/config/services.xml | 1 + Security/Firewall/OAuth2Listener.php | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 09295d02..7b1c9194 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -85,6 +85,7 @@ + The "%alias_id%" service alias is deprecated and will be removed in v4. diff --git a/Security/Firewall/OAuth2Listener.php b/Security/Firewall/OAuth2Listener.php index 36330fc7..56788e61 100644 --- a/Security/Firewall/OAuth2Listener.php +++ b/Security/Firewall/OAuth2Listener.php @@ -5,6 +5,7 @@ namespace Trikoder\Bundle\OAuth2Bundle\Security\Firewall; use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; @@ -37,6 +38,11 @@ final class OAuth2Listener */ private $oauth2TokenFactory; + /** + * @var EventDispatcherInterface + */ + private $eventDispatcher; + /** * @var string */ @@ -47,12 +53,14 @@ public function __construct( AuthenticationManagerInterface $authenticationManager, HttpMessageFactoryInterface $httpMessageFactory, OAuth2TokenFactory $oauth2TokenFactory, + EventDispatcherInterface $eventDispatcher, string $providerKey ) { $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; $this->httpMessageFactory = $httpMessageFactory; $this->oauth2TokenFactory = $oauth2TokenFactory; + $this->eventDispatcher = $eventDispatcher; $this->providerKey = $providerKey; } From cd2329363a58b04e9205eca94e02172852937e62 Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Sun, 6 Dec 2020 16:16:56 +0100 Subject: [PATCH 07/10] FIX: Wrong position of eventDispatcher --- Resources/config/services.xml | 2 +- Security/Firewall/OAuth2Listener.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 7b1c9194..de58344c 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -84,8 +84,8 @@ - + The "%alias_id%" service alias is deprecated and will be removed in v4. diff --git a/Security/Firewall/OAuth2Listener.php b/Security/Firewall/OAuth2Listener.php index 57843052..3bd3a798 100644 --- a/Security/Firewall/OAuth2Listener.php +++ b/Security/Firewall/OAuth2Listener.php @@ -52,15 +52,15 @@ public function __construct( TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, HttpMessageFactoryInterface $httpMessageFactory, - OAuth2TokenFactory $oauth2TokenFactory, EventDispatcherInterface $eventDispatcher, + OAuth2TokenFactory $oauth2TokenFactory, string $providerKey ) { $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; $this->httpMessageFactory = $httpMessageFactory; - $this->oauth2TokenFactory = $oauth2TokenFactory; $this->eventDispatcher = $eventDispatcher; + $this->oauth2TokenFactory = $oauth2TokenFactory; $this->providerKey = $providerKey; } From edadddb2b096872faf26e9ef433148c8e67d2a31 Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Sun, 6 Dec 2020 17:39:26 +0100 Subject: [PATCH 08/10] ADD: Create the AUTHENTICATION_FAILURE event --- Event/AuthenticationFailureEvent.php | 52 +++++++++++++++++++ OAuth2Events.php | 13 +++-- .../OAuth2AuthenticationFailedException.php | 14 ++--- Security/Firewall/OAuth2Listener.php | 14 ++++- 4 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 Event/AuthenticationFailureEvent.php diff --git a/Event/AuthenticationFailureEvent.php b/Event/AuthenticationFailureEvent.php new file mode 100644 index 00000000..3efab875 --- /dev/null +++ b/Event/AuthenticationFailureEvent.php @@ -0,0 +1,52 @@ + + */ +class AuthenticationFailureEvent extends Event { + /** + * @var AuthenticationException + */ + protected $exception; + + /** + * @var Response + */ + protected $response; + + /** + * @param AuthenticationException $exception + * @param Response $response + */ + public function __construct(AuthenticationException $exception, Response $response) { + $this->exception = $exception; + $this->response = $response; + } + + /** + * @return AuthenticationException + */ + public function getException(): AuthenticationException { + return $this->exception; + } + + /** + * @return Response + */ + public function getResponse(): Response { + return $this->response; + } + + /** + * @param Response $response + */ + public function setResponse(Response $response): void { + $this->response = $response; + } +} diff --git a/OAuth2Events.php b/OAuth2Events.php index 8894eb9d..836ffe33 100644 --- a/OAuth2Events.php +++ b/OAuth2Events.php @@ -7,7 +7,7 @@ final class OAuth2Events { /** - * The USER_RESOLVE event occurrs when the client requests a "password" + * The USER_RESOLVE event occurs when the client requests a "password" * grant type from the authorization server. * * You should set a valid user here if applicable. @@ -15,7 +15,7 @@ final class OAuth2Events public const USER_RESOLVE = 'trikoder.oauth2.user_resolve'; /** - * The SCOPE_RESOLVE event occurrs right before the user obtains their + * The SCOPE_RESOLVE event occurs right before the user obtains their * valid access token. * * You could alter the access token's scope here. @@ -23,11 +23,18 @@ final class OAuth2Events public const SCOPE_RESOLVE = 'trikoder.oauth2.scope_resolve'; /** - * The AUTHORIZATION_REQUEST_RESOLVE event occurrs right before the system + * The AUTHORIZATION_REQUEST_RESOLVE event occurs right before the system * complete the authorization request. * * You could approve or deny the authorization request, or set the uri where * must be redirected to resolve the authorization request. */ public const AUTHORIZATION_REQUEST_RESOLVE = 'trikoder.oauth2.authorization_request_resolve'; + + /** + * The AUTHENTICATION_FAILURE event occurs when the oauth token wasn't found + * + * You can set a custom error message in the response body + */ + public const AUTHENTICATION_FAILURE = 'trikoder.oauth2.autentication_failure'; } diff --git a/Security/Exception/OAuth2AuthenticationFailedException.php b/Security/Exception/OAuth2AuthenticationFailedException.php index 35d8fd20..00580998 100644 --- a/Security/Exception/OAuth2AuthenticationFailedException.php +++ b/Security/Exception/OAuth2AuthenticationFailedException.php @@ -1,19 +1,19 @@ - + * @author Benoit VIGNAL */ class OAuth2AuthenticationFailedException extends AuthenticationException { - public static function create(string $message, ?Throwable $previous = null): self - { - return new self($message, 401, $previous); + /** + * {@inheritdoc} + */ + public function getMessageKey(): string { + return "OAuth Token not found"; } } diff --git a/Security/Firewall/OAuth2Listener.php b/Security/Firewall/OAuth2Listener.php index 3bd3a798..e617138b 100644 --- a/Security/Firewall/OAuth2Listener.php +++ b/Security/Firewall/OAuth2Listener.php @@ -7,10 +7,13 @@ use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Trikoder\Bundle\OAuth2Bundle\Event\AuthenticationFailureEvent; +use Trikoder\Bundle\OAuth2Bundle\OAuth2Events; use Trikoder\Bundle\OAuth2Bundle\Security\Authentication\Token\OAuth2Token; use Trikoder\Bundle\OAuth2Bundle\Security\Authentication\Token\OAuth2TokenFactory; use Trikoder\Bundle\OAuth2Bundle\Security\Exception\InsufficientScopesException; @@ -76,7 +79,16 @@ public function __invoke(RequestEvent $event) /** @var OAuth2Token $authenticatedToken */ $authenticatedToken = $this->authenticationManager->authenticate($this->oauth2TokenFactory->createOAuth2Token($request, null, $this->providerKey)); } catch (AuthenticationException $e) { - throw OAuth2AuthenticationFailedException::create($e->getMessage(), $e); + $exception = new OAuth2AuthenticationFailedException("OAuth Token not found", 0, $e); + $response = new Response($exception->getMessageKey(), Response::HTTP_UNAUTHORIZED); + + $authenticationFailureEvent = new AuthenticationFailureEvent($exception, $response); + $this->eventDispatcher->dispatch($authenticationFailureEvent, OAuth2Events::AUTHENTICATION_FAILURE); + + if ($response = $authenticationFailureEvent->getResponse()) { + $event->setResponse($response); + } + return; } if (!$this->isAccessToRouteGranted($event->getRequest(), $authenticatedToken)) { From cb97c2ee84644b8af7227789f288e3c8ac40de90 Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Sun, 6 Dec 2020 18:25:13 +0100 Subject: [PATCH 09/10] ADD: Create the AUTHENTICATION_FAILURE event --- .../OAuth2AuthenticationFailedException.php | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 Security/Exception/OAuth2AuthenticationFailedException.php diff --git a/Security/Exception/OAuth2AuthenticationFailedException.php b/Security/Exception/OAuth2AuthenticationFailedException.php deleted file mode 100644 index 00580998..00000000 --- a/Security/Exception/OAuth2AuthenticationFailedException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @author Benoit VIGNAL - */ -class OAuth2AuthenticationFailedException extends AuthenticationException -{ - /** - * {@inheritdoc} - */ - public function getMessageKey(): string { - return "OAuth Token not found"; - } -} From c5f13918f157016c5f51efe8698da6cdbd2dbd87 Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Sun, 6 Dec 2020 18:25:24 +0100 Subject: [PATCH 10/10] ADD: Create the AUTHENTICATION_FAILURE event --- .../OAuth2AuthenticationFailedException.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Security/Exception/OAuth2AuthenticationFailedException.php diff --git a/Security/Exception/OAuth2AuthenticationFailedException.php b/Security/Exception/OAuth2AuthenticationFailedException.php new file mode 100644 index 00000000..00580998 --- /dev/null +++ b/Security/Exception/OAuth2AuthenticationFailedException.php @@ -0,0 +1,19 @@ + + * @author Benoit VIGNAL + */ +class OAuth2AuthenticationFailedException extends AuthenticationException +{ + /** + * {@inheritdoc} + */ + public function getMessageKey(): string { + return "OAuth Token not found"; + } +}