OpenID Connect support to the PHP League's OAuth2 Server.
This is a fork of ronvanderheijden/openid-connect.
It's made to support only Laravel and Laravel Passport.
- Requires PHP version
^8.2
. - lcobucci/jwt version
^4.0
. - league/oauth2-server
^8.2
. - Laravel 10 or Laravel 11
- Laravel Passport installed and configured
composer require jeremy379/laravel-openid-connect
Now when calling the oauth/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
.
The id_token will be returned after the call to the oauth/token
endpoint.
Passport::tokensCan(config('openid.passport.tokens_can'));
You may want to combine existing scope and oauth implementation with the open ID connect.
$scopes = array_merge($yourScope, config('openid.passport.tokens_can'));
Passport::tokensCan($scopes);
Create an entity class in app/Entities/
named IdentityEntity
or UserEntity
. This entity is used to collect the claims.
You can customize the entity setup by using another IdentityRepository, this is customizable in the config file.
# 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,
];
}
}
Here is an example to verify the signature with lcobucci/jwt
$config = Configuration::forSymmetricSigner(
new \Lcobucci\JWT\Signer\Rsa\Sha256(),
InMemory::file(base_path('oauth-public.key')) //This is the public key generate by passport. You need to share it.
);
//Parse the token
$token = $config->parser()->parse($idtoken);
$signatureValid = $config->validator()->validate($token, new \Lcobucci\JWT\Validation\Constraint\SignedWith($config->signer(), $config->signingKey()));
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
When nonce
is required, you need to pass it as a query parameter to passport.authorizations.approve
during authorization step.
Example based on default Passport's authorize.blade.php
:
<form method="post" action="{{ route('passport.authorizations.approve').'?nonce='.$request->nonce }}">
You can add any JWT Token Headers that you want to the token_headers
array in your openid
configuration file.
This can be useful to define things like the kid
(Key ID). The kid
can be any string as long as it can uniquely identify the key you want to use in your JWKS. This can be useful when changing or rolling keys.
Example:
'token_headers' => ['kid' => base64_encode('public-key-added-2023-01-01')]
Additionally, you can configure the JWKS url and some settings for discovery in the config file.
Note: If you define a kid
header, it will be added to the JWK returned at the jwks_url (if jwks
is enabled in the configuration).
You can fill an issue in the github section dedicated for that. I'll try to maintain this fork.
OpenID Connect is open source and licensed under the MIT licence.