OpenID Connect support to the PHP League's OAuth2 Server.
Compatible with Laravel Passport!
- Requires PHP version
^7.4|^8.0
. - lcobucci/jwt version
^4.0
. - league/oauth2-server
^8.2
.
composer require ronvanderheijden/openid-connect
To sign and encrypt the tokens, we need a private and a public key.
mkdir -m 700 -p tmp
openssl genrsa -out tmp/private.key 2048
openssl rsa -in tmp/private.key -pubout -out tmp/public.key
chmod 600 tmp/private.key
chmod 644 tmp/public.key
I recommend to read this first.
To enable OpenID Connect, follow these simple steps
$privateKeyPath = 'tmp/private.key';
$currentRequestService = new CurrentRequestService();
$currentRequestService->setRequest(ServerRequestFactory::fromGlobals());
// create the response_type
$responseType = new IdTokenResponse(
new IdentityRepository(),
new ClaimExtractor(),
Configuration::forSymmetricSigner(
new Sha256(),
InMemory::file($privateKeyPath),
),
$currentRequestService,
$encryptionKey,
);
$server = new \League\OAuth2\Server\AuthorizationServer(
$clientRepository,
$accessTokenRepository,
$scopeRepository,
$privateKeyPath,
$encryptionKey,
// add the response_type
$responseType,
);
Now when calling the /authorize
endpoint, provide the openid
scope to get an id_token
.
Provide more scopes (e.g. openid profile email
) to receive additional claims in the id_token
.
For a complete implementation, visit the OAuth2 Server example.
To prevent replay attacks, some clients can provide a "nonce" in the authorization request. If a client does so, the
server MUST include back a nonce
claim in the id_token
.
To enable this feature, when registering an AuthCodeGrant, you need to use the \OpenIDConnect\Grant\AuthCodeGrant
instead of \League\OAuth2\Server\Grant\AuthCodeGrant
.
![NOTE] If you are using Laravel, the
AuthCodeGrant
is already registered for you by the service provider.
You can use this package with Laravel Passport in 2 simple steps.
# config/app.php
'providers' => [
/*
* Package Service Providers...
*/
OpenIDConnect\Laravel\PassportServiceProvider::class,
],
Create an entity class in app/Entities/
named IdentityEntity
or UserEntity
. This entity is used to collect the claims.
# app/Entities/IdentityEntity.php
namespace App\Entities;
use League\OAuth2\Server\Entities\Traits\EntityTrait;
use OpenIDConnect\Claims\Traits\WithClaims;
use OpenIDConnect\Interfaces\IdentityEntityInterface;
class IdentityEntity implements IdentityEntityInterface
{
use EntityTrait;
use WithClaims;
/**
* The user to collect the additional information for
*/
protected User $user;
/**
* The identity repository creates this entity and provides the user id
* @param mixed $identifier
*/
public function setIdentifier($identifier): void
{
$this->identifier = $identifier;
$this->user = User::findOrFail($identifier);
}
/**
* When building the id_token, this entity's claims are collected
*/
public function getClaims(): array
{
return [
'email' => $this->user->email,
];
}
}
In case you want to change the default scopes, add custom claim sets or change the repositories, you can publish the openid config using:
php artisan vendor:publish --tag=openid
The Laravel Passport integration also provides:
- a discovery endpoint at
/.well-known/openid-configuration
. - a JWKS endpoint at
/oauth/jwks
.
Those 2 endpoints are automatically added to the Laravel routes and can be disabled from the config (using
the openid.routes.discovery
and openid.routes.jwks
keys).
Laravel Passport does not provide a userinfo
endpoint by default. If you provide one, you can add it to the
discovery document by naming the route openid.userinfo
.
Route::get('/oauth/userinfo', 'YourController@userinfo')->middleware('xxx')->name('openid.userinfo');
Found a bug? Got a feature request? Create an issue.
OpenID Connect is open source and licensed under the MIT licence.