thephpleague / oauth2-server

A spec compliant, secure by default PHP OAuth 2.0 Server
https://oauth2.thephpleague.com
MIT License
6.49k stars 1.12k forks source link

how to validate client when exchanging auth code for access token #1370

Closed akshare closed 10 months ago

akshare commented 10 months ago

I'm able to generate access token and refresh token with authorization code grant + pkce using thephpleague client+server.

When auth code is exchanged for access token, how can I validate the client (client_secret), so that only authorized clients from a list have access?

Right now, I can set random clients/secrets and access_token is generated nonetheless.

Any help to point me in the right direction would be really appreciated!

This is my ClientEntity.php

class ClientEntity implements \League\OAuth2\Server\Entities\ClientEntityInterface
{
    use \League\OAuth2\Server\Entities\Traits\ClientTrait;
    use \League\OAuth2\Server\Entities\Traits\EntityTrait;

    public function __construct()
    {
        $this->name = 'The client App';
        $this->setIdentifier("MyApp");
        $this->redirectUri = "link to process-auth-code.php";;
    }
}

This is my ClientRepository.php (I'm guessing, I have to use validateClient() somewhere in access-token.php?)

class ClientRepository implements \League\OAuth2\Server\Repositories\ClientRepositoryInterface
{

    /**
     * @inheritDoc
     */
    public function getClientEntity($clientIdentifier)
    {
        $theClient = new ClientEntity();
        $theClient->setIdentifier($clientIdentifier);

        return $theClient;
    }

    /**
     * @inheritDoc
     */
    public function validateClient($clientIdentifier, $clientSecret, $grantType)
    {
        return true;
    }
}

This is my access-token.php endpoint.

require_once 'bootstrap.php';

use League\OAuth2\Server\Exception\OAuthServerException;

try {

    $response = $server->respondToAccessTokenRequest($request, $response);

} catch (\League\OAuth2\Server\Exception\OAuthServerException $exception) {

    $response = $exception->generateHttpResponse($response);

} catch (\Exception $exception) {

    $body = new Stream(fopen('php://temp', 'r+'));
    $body->write($exception->getMessage());

    $response = $response->withStatus(500)->withBody($body);
}

require_once 'output.php';
akshare commented 10 months ago

Figured it out.

I needed to set isConfidential to true in ClientEntity.php and then add the conditions to check for client_id and secret within validateClient() in ClientRepository.php

My updated ClientEntity.php

class ClientEntity implements \League\OAuth2\Server\Entities\ClientEntityInterface
{
    use \League\OAuth2\Server\Entities\Traits\ClientTrait;
    use \League\OAuth2\Server\Entities\Traits\EntityTrait;

    public function __construct()
    {
        $this->isConfidential = true;
        $this->name = 'The client App';
        $this->setIdentifier("MyApp");
        $this->redirectUri = "link to process-auth-code.php";
    }
}

My updated ClientRepository.php

class ClientRepository implements \League\OAuth2\Server\Repositories\ClientRepositoryInterface
{

    public function getClientEntity($clientIdentifier)
    {
        $theClient = new ClientEntity();
        $theClient->setIdentifier($clientIdentifier);

        return $theClient;
    }

    public function validateClient($clientIdentifier, $clientSecret, $grantType)
    {
         if($clientIdentifier == "MyApp" && $clientSecret == "MyAppSecret"){
            return true;
        }

        return false;
    }
}