jeremy379/laravel-openid-connect

为 PHP League 的 OAuth2 Server 提供OpenID Connect 支持。与 Laravel Passport 兼容。

2.4.0 2024-09-09 07:17 UTC

README

PHP 8.2

Laravel 的 OpenID Connect

为 PHP League 的 OAuth2 Server 提供OpenID Connect 支持。

这是基于 ronvanderheijden/openid-connect 的分支。

仅支持 Laravel 和 Laravel Passport

要求

安装

composer require jeremy379/laravel-openid-connect

现在在调用 oauth/authorize 端点时,提供 openid 范围以获取 id_token
提供更多范围(例如 openid profile email)以在 id_token 中接收额外的声明。

在调用 oauth/token 端点后,将返回 id_token。

配置

1.) 在 AuthServiceProvider 的 boot() 方法中添加范围。

Passport::tokensCan(config('openid.passport.tokens_can'));

您可能希望将现有范围和 oauth 实现与 Open ID Connect 结合使用。

$scopes = array_merge($yourScope, config('openid.passport.tokens_can'));
Passport::tokensCan($scopes);

2.) 创建一个实体

app/Entities/ 中创建一个名为 IdentityEntityUserEntity 的实体类。此实体用于收集声明。

您可以通过使用另一个 IdentityRepository 来自定义实体设置,这在配置文件中是可定制的。

# 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,
        ];
    }
}

id_token 是 JWT,客户端应验证签名。

以下是一个使用 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()));

发布配置

如果您想更改默认范围、添加自定义声明集或更改存储库,可以使用以下命令发布 openid 配置

php artisan vendor:publish --tag=openid

使用 nonce

当需要 nonce 时,您需要在授权步骤中将它作为查询参数传递给 passport.authorizations.approve

基于默认 Passport 的 authorize.blade.php 的示例

<form method="post" action="{{ route('passport.authorizations.approve').'?nonce='.$request->nonce }}">

可选配置

您可以将任何 JWT Token Headers 添加到您的 openid 配置文件中的 token_headers 数组中。

这可以用于定义如 kid(密钥 ID) 之类的项目。只要它能唯一标识您想要在您的 JWKS 中使用的密钥,就可以使用任何字符串作为 kid。这在更改或轮换密钥时非常有用。

示例

'token_headers' => ['kid' => base64_encode('public-key-added-2023-01-01')]

此外,您还可以在配置文件中配置 JWKS URL 和一些发现设置。

注意:如果您定义了 kid 头部,它将被添加到在 jwks_url 返回的 JWK 中(如果配置中启用了 jwks)。

支持

您可以在为该目的专设的 GitHub 部分中提出问题。我会尽量维护这个分支。

许可

OpenID Connect 是开源的,并使用 MIT 许可证 许可。