From 285cd3fa5514954274463552e8d965869c2787ed Mon Sep 17 00:00:00 2001 From: Fred Cox Date: Wed, 9 Aug 2017 18:09:20 +0300 Subject: [PATCH] Dont throw exception when credentials are missing This allows to combine the listeners with other firewalls For example an api might have resource listener and a basic auth listener --- .../AuthBucketOAuth2ServiceProvider.php | 14 ++++++++++++-- .../ResourceAuthenticationEntryPoint.php | 18 ++++++++++++++++++ .../TokenAuthenticationEntryPoint.php | 18 ++++++++++++++++++ .../Http/Firewall/ResourceListener.php | 5 ++--- .../Security/Http/Firewall/TokenListener.php | 5 +++++ tests/Controller/OAuth2ControllerTest.php | 1 + tests/TokenType/BearerTokenTypeHandlerTest.php | 4 ++-- 7 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/Symfony/Component/Security/Http/EntryPoint/ResourceAuthenticationEntryPoint.php create mode 100644 src/Symfony/Component/Security/Http/EntryPoint/TokenAuthenticationEntryPoint.php diff --git a/src/Silex/Provider/AuthBucketOAuth2ServiceProvider.php b/src/Silex/Provider/AuthBucketOAuth2ServiceProvider.php index ae9fb554..8bc1a980 100644 --- a/src/Silex/Provider/AuthBucketOAuth2ServiceProvider.php +++ b/src/Silex/Provider/AuthBucketOAuth2ServiceProvider.php @@ -20,6 +20,8 @@ use AuthBucket\OAuth2\Symfony\Component\EventDispatcher\ExceptionListener; use AuthBucket\OAuth2\Symfony\Component\Security\Core\Authentication\Provider\ResourceProvider; use AuthBucket\OAuth2\Symfony\Component\Security\Core\Authentication\Provider\TokenProvider; +use AuthBucket\OAuth2\Symfony\Component\Security\Http\EntryPoint\ResourceAuthenticationEntryPoint; +use AuthBucket\OAuth2\Symfony\Component\Security\Http\EntryPoint\TokenAuthenticationEntryPoint; use AuthBucket\OAuth2\Symfony\Component\Security\Http\Firewall\ResourceListener; use AuthBucket\OAuth2\Symfony\Component\Security\Http\Firewall\TokenListener; use AuthBucket\OAuth2\TokenType\TokenTypeHandlerFactory; @@ -149,6 +151,14 @@ public function register(Container $app) ); }; + $app['authbucket_oauth2.token_entry_point'] = function () { + return new TokenAuthenticationEntryPoint(); + }; + + $app['authbucket_oauth2.resource_entry_point'] = function () { + return new ResourceAuthenticationEntryPoint(); + }; + $app['security.authentication_provider.oauth2_token._proto'] = $app->protect(function ($name, $options) use ($app) { return function () use ($app, $name, $options) { return new TokenProvider( @@ -207,7 +217,7 @@ public function register(Container $app) return [ 'security.authentication_provider.'.$name.'.oauth2_token', 'security.authentication_listener.'.$name.'.oauth2_token', - null, + 'authbucket_oauth2.token_entry_point', 'pre_auth', ]; }); @@ -230,7 +240,7 @@ public function register(Container $app) return [ 'security.authentication_provider.'.$name.'.oauth2_resource', 'security.authentication_listener.'.$name.'.oauth2_resource', - null, + 'authbucket_oauth2.resource_entry_point', 'pre_auth', ]; }); diff --git a/src/Symfony/Component/Security/Http/EntryPoint/ResourceAuthenticationEntryPoint.php b/src/Symfony/Component/Security/Http/EntryPoint/ResourceAuthenticationEntryPoint.php new file mode 100644 index 00000000..9e0ec849 --- /dev/null +++ b/src/Symfony/Component/Security/Http/EntryPoint/ResourceAuthenticationEntryPoint.php @@ -0,0 +1,18 @@ +'invalid_request', 'error_message' => 'Authentication token required'], 401); + } +} diff --git a/src/Symfony/Component/Security/Http/EntryPoint/TokenAuthenticationEntryPoint.php b/src/Symfony/Component/Security/Http/EntryPoint/TokenAuthenticationEntryPoint.php new file mode 100644 index 00000000..8f9a7330 --- /dev/null +++ b/src/Symfony/Component/Security/Http/EntryPoint/TokenAuthenticationEntryPoint.php @@ -0,0 +1,18 @@ +'invalid_request', 'error_message' => 'Client id and secret required'], 401); + } +} diff --git a/src/Symfony/Component/Security/Http/Firewall/ResourceListener.php b/src/Symfony/Component/Security/Http/Firewall/ResourceListener.php index eed56d85..1aca19e3 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ResourceListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ResourceListener.php @@ -68,10 +68,9 @@ public function handle(GetResponseEvent $event) continue; } } + // If there is no access token then dont continue if ($accessToken === null) { - throw new InvalidRequestException([ - 'error_description' => 'The request includes an invalid parameter value.', - ]); + return; } // access_token must in valid format. diff --git a/src/Symfony/Component/Security/Http/Firewall/TokenListener.php b/src/Symfony/Component/Security/Http/Firewall/TokenListener.php index 25409fa9..43ac35f1 100644 --- a/src/Symfony/Component/Security/Http/Firewall/TokenListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/TokenListener.php @@ -72,6 +72,11 @@ public function handle(GetResponseEvent $event) $clientSecret = $request->request->get('client_secret', false); } + // If there is no client then dont continue + if ($clientId === false && $clientSecret === false) { + return; + } + // client_id must in valid format. $errors = $this->validator->validate($clientId, [ new \Symfony\Component\Validator\Constraints\NotBlank(), diff --git a/tests/Controller/OAuth2ControllerTest.php b/tests/Controller/OAuth2ControllerTest.php index 87217e1e..3c0ce5eb 100644 --- a/tests/Controller/OAuth2ControllerTest.php +++ b/tests/Controller/OAuth2ControllerTest.php @@ -152,6 +152,7 @@ public function testExceptionBadAccessToken() ]; $client = $this->createClient(); $crawler = $client->request('GET', '/api/oauth2/debug', $parameters, [], $server); + $this->assertEquals(401, $client->getResponse()->getStatusCode()); $resourceResponse = json_decode($client->getResponse()->getContent(), true); $this->assertSame('invalid_request', $resourceResponse['error']); } diff --git a/tests/TokenType/BearerTokenTypeHandlerTest.php b/tests/TokenType/BearerTokenTypeHandlerTest.php index e754b411..7e4cf724 100644 --- a/tests/TokenType/BearerTokenTypeHandlerTest.php +++ b/tests/TokenType/BearerTokenTypeHandlerTest.php @@ -22,7 +22,7 @@ public function testExceptionNoToken() $server = []; $client = $this->createClient(); $crawler = $client->request('GET', '/api/oauth2/debug', $parameters, [], $server); - $this->assertSame(400, $client->getResponse()->getStatusCode()); + $this->assertSame(401, $client->getResponse()->getStatusCode()); $this->assertNotNull(json_decode($client->getResponse()->getContent())); $tokenResponse = json_decode($client->getResponse()->getContent(), true); $this->assertSame('invalid_request', $tokenResponse['error']); @@ -38,7 +38,7 @@ public function testExceptionDuplicateToken() ]; $client = $this->createClient(); $crawler = $client->request('GET', '/api/oauth2/debug', $parameters, [], $server); - $this->assertSame(400, $client->getResponse()->getStatusCode()); + $this->assertSame(401, $client->getResponse()->getStatusCode()); $this->assertNotNull(json_decode($client->getResponse()->getContent())); $tokenResponse = json_decode($client->getResponse()->getContent(), true); $this->assertSame('invalid_request', $tokenResponse['error']);