thephpleague / oauth2-server

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

ResourceServer depends on key stored in file #1194

Closed fabiante closed 3 years ago

fabiante commented 3 years ago

Hi,

I have a question about the \League\OAuth2\Server\ResourceServer class. I'm currently trying to integrate Keycloak as an identity provider. I am struggling to find a way where the public key is dynamically loaded from keycloaks API rather than being stored in a file.

Any idea on how to archive this? To me it seems that the \League\OAuth2\Server\ResourceServer API wasn't really constructed to support such a use case.

Sephster commented 3 years ago

Have you got any documentation I can look at for Keycloak to see how it expects this to work? Thanks

fabiante commented 3 years ago

Hi @Sephster! In the last 2 weeks I have coded a proprietary solution using a basic JWT validation package and a selfmade PHP class that simply fetches the public keys from Keycloak. When I created this issue I didn't know that what I was looking for was an API endpoint that returns a JWK / a JWKS.

The Keycloak endpoint I ended up using is mentioned in this paragraph: https://www.keycloak.org/docs/4.8/securing_apps/#_certificate_endpoint

That endpoint returns a x5c property, which contains a certificat which can be used to calculate the public key. I don't really know why the key is not present in a plain text form 🤷🏻‍♂️

That being said, when I created this issue I was simply wondering, why the oauth2-server API does not allow setting a key from a PHP variable:

$server = new \League\OAuth2\Server\ResourceServer(
    $accessTokenRepository,
    $publicKeyPath
)

As a user of this library I was missing the option to specify the key as a variable or even better, supply a class that implements an interface similar to this one:

interface PublicKeyProvider
{
    public function getPublicKey(\Psr\Http\Message\RequestInterface $request): KeyInterface;
}
Sephster commented 3 years ago

@FabianTe you can set the public key in the ResourceServer. It is the second constructor parameter and it allows you to pass in either a CryptKey object or the plain key string.

There is also a PR submitted to change the key to be able to be stored in memory instead of a file which should be merged in soon. I'm hopeful both of these things will solve your problem but if not, please feel free to reply here and I will reopen the ticket.