diff --git a/CHANGELOG.md b/CHANGELOG.md index 04c42c32..d9276547 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. 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] + +### Fixed +- Clients are now explicitly prevented from using the Client Credentials grant unless they are confidential to conform + with the OAuth2 spec (PR #1035) + ## [8.0.0] - released 2019-07-13 ### Added diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 9f647965..691f421b 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -12,6 +12,7 @@ namespace League\OAuth2\Server\Grant; use DateInterval; +use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\RequestEvent; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use Psr\Http\Message\ServerRequestInterface; @@ -29,8 +30,19 @@ class ClientCredentialsGrant extends AbstractGrant ResponseTypeInterface $responseType, DateInterval $accessTokenTTL ) { + list($clientId) = $this->getClientCredentials($request); + + $client = $this->getClientEntityOrFail($clientId, $request); + + if (!$client->isConfidential()) { + $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); + + throw OAuthServerException::invalidClient($request); + } + // Validate request - $client = $this->validateClient($request); + $this->validateClient($request); + $scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope)); // Finalize the requested scopes diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index bcd87b5b..870d546f 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -62,8 +62,11 @@ class AuthorizationServerTest extends TestCase public function testRespondToRequest() { + $client = new ClientEntity(); + $client->setConfidential(); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); - $clientRepository->method('getClientEntity')->willReturn(new ClientEntity()); + $clientRepository->method('getClientEntity')->willReturn($client); $scope = new ScopeEntity(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index 54be52fd..78408a33 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -29,6 +29,8 @@ class ClientCredentialsGrantTest extends TestCase public function testRespondToRequest() { $client = new ClientEntity(); + $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); diff --git a/tests/Middleware/AuthorizationServerMiddlewareTest.php b/tests/Middleware/AuthorizationServerMiddlewareTest.php index c8ed7d1a..e861c7c4 100644 --- a/tests/Middleware/AuthorizationServerMiddlewareTest.php +++ b/tests/Middleware/AuthorizationServerMiddlewareTest.php @@ -24,8 +24,11 @@ class AuthorizationServerMiddlewareTest extends TestCase public function testValidResponse() { + $client = new ClientEntity(); + $client->setConfidential(); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); - $clientRepository->method('getClientEntity')->willReturn(new ClientEntity()); + $clientRepository->method('getClientEntity')->willReturn($client); $scopeEntity = new ScopeEntity; $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();