Prevent public clients from using the client_credentials grant type

See https://tools.ietf.org/html/rfc6749#section-4.4.2
This commit is contained in:
Matt Allan 2019-07-22 17:34:54 -04:00
parent e1dc4d708c
commit 3413c20590
4 changed files with 21 additions and 3 deletions

View File

@ -12,6 +12,7 @@
namespace League\OAuth2\Server\Grant; namespace League\OAuth2\Server\Grant;
use DateInterval; use DateInterval;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\RequestEvent; use League\OAuth2\Server\RequestEvent;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@ -29,8 +30,18 @@ class ClientCredentialsGrant extends AbstractGrant
ResponseTypeInterface $responseType, ResponseTypeInterface $responseType,
DateInterval $accessTokenTTL 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 // Validate request
$client = $this->validateClient($request); $this->validateClient($request);
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope)); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope));
// Finalize the requested scopes // Finalize the requested scopes

View File

@ -62,8 +62,11 @@ class AuthorizationServerTest extends TestCase
public function testRespondToRequest() public function testRespondToRequest()
{ {
$client = new ClientEntity();
$client->setConfidential();
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepository->method('getClientEntity')->willReturn(new ClientEntity()); $clientRepository->method('getClientEntity')->willReturn($client);
$scope = new ScopeEntity(); $scope = new ScopeEntity();
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();

View File

@ -29,6 +29,7 @@ class ClientCredentialsGrantTest extends TestCase
public function testRespondToRequest() public function testRespondToRequest()
{ {
$client = new ClientEntity(); $client = new ClientEntity();
$client->setConfidential();
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock->method('getClientEntity')->willReturn($client); $clientRepositoryMock->method('getClientEntity')->willReturn($client);

View File

@ -24,8 +24,11 @@ class AuthorizationServerMiddlewareTest extends TestCase
public function testValidResponse() public function testValidResponse()
{ {
$client = new ClientEntity();
$client->setConfidential();
$clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepository->method('getClientEntity')->willReturn(new ClientEntity()); $clientRepository->method('getClientEntity')->willReturn($client);
$scopeEntity = new ScopeEntity; $scopeEntity = new ScopeEntity;
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();