maicol07/oidc-client

OpenID Connect 客户端

4.0-rc1 2024-09-10 17:23 UTC

README

这是一个简单的库,允许应用程序通过基本的 OpenID Connect 流进行用户认证。这个库希望通过使其足够简单,以便对 OpenID Connect 协议了解不多的开发者可以设置认证来鼓励 OpenID Connect 的使用。

支持的规范

测试提供者

注意:此列表并不详尽。其他通用的 OIDC 提供者也应该可以工作。如果您已在此列表中未列出的提供者上测试过此库,请打开 PR 以将其添加到列表,并添加测试配置(.run 目录)。

需求

  1. PHP 8.1+
  2. JSON 扩展
  3. MBString 扩展
  4. (可选)GMP 或 BCMath 扩展之一,以允许更快的密钥操作(用于 JWT;有关更多信息,请参阅此处

安装

使用 composer 安装

composer require maicol07/oidc-client-php

示例

示例 1:基本客户端

此示例使用授权代码流,并且如果 OpenID 提供者在其发现文档中声明,还将使用 PKCE。如果您不确定应该选择哪种流:这是一个不错的选择。它是最高效和最通用的。

use Maicol07\OpenIDConnect\Client;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php',
);
$oidc->authenticate();
$name = $oidc->getUserInfo()->given_name;

请参阅 OpenID Connect 规范以获取可用的用户属性

示例 2:动态注册

use Maicol07\OpenIDConnect\Client;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    redirect_uri: 'https://example.com/callback.php',
    client_name: 'My Client',
);

$oidc->register();
[$client_id, $client_secret] = $oidc->getClientCredentials();

// Be sure to add logic to store the client id and client secret

示例 3:网络和安全

您应该始终为您的应用程序使用 HTTPS。如果您正在使用自签名证书,可以禁用 SSL 验证,通过设置客户端上的 verify_ssl 属性,如果有的话,在 cert_path 属性中设置自定义证书(此操作仅在 verifySsl 设置为 false 时有效)。

您也可以通过 http_proxy 设置代理。

use Maicol07\OpenIDConnect\Client;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php',
    http_proxy: 'http://proxy.example.com:8080',
    cert_path: 'path/to/cert.pem',
    verify_ssl: false
);

示例 4:隐式流

参考:https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth

隐式流应被视为旧版流,并且如果可以使用授权代码授予,则不应使用。由于其缺点和安全性差,隐式流将被即将推出的 OAuth 2.1 标准所淘汰。请参阅示例 1 以获取替代方案。

use Maicol07\OpenIDConnect\Client;
use Maicol07\OpenIDConnect\ResponseType;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php',
    response_type: ResponseType::ID_TOKEN,
    allow_implicit_flow: true,
);
$oidc->authenticate();
$sub = $oidc->getUserInfo()->sub;

示例 5:访问令牌的内省

参考:https://tools.ietf.org/html/rfc7662

use Maicol07\OpenIDConnect\Client;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php'
);

$data = $oidc->introspectToken('an.access-token.as.given');
if (!$data->get('active')) {
    // the token is no longer usable
}

示例 6:PKCE 客户端

在示例1中,PKCE已经配置并用于大多数场景。本示例展示了如何显式设置初始配置中的Code Challenge Method。这可以使PKCE在您的OpenID Provider在发现文档中未声明支持但仍然支持的情况下启用。

use Maicol07\OpenIDConnect\Client;
use Maicol07\OpenIDConnect\CodeChallengeMethod;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php',
    // for some reason we want to set S256 explicitly as Code Challenge Method
    // maybe your OP doesn’t announce support for PKCE in its discovery document.
    code_challenge_method: CodeChallengeMethod::S256
);

$oidc->authenticate();
$name = $oidc->getUserInfo()->given_name;

示例7:令牌端点认证方法

默认情况下,客户端端只启用了client_secret_basic,这在很长一段时间内是唯一支持的。最近添加了client_secret_jwtprivate_key_jwt,但它们在未显式启用的情况下保持禁用。

use Maicol07\OpenIDConnect\Client;
use Maicol07\OpenIDConnect\TokenEndpointAuthMethod;

$oidc = new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php',
    token_endpoint_auth_methods_supported: [
        TokenEndpointAuthMethod::CLIENT_SECRET_BASIC,
        TokenEndpointAuthMethod::CLIENT_SECRET_JWT,
        TokenEndpointAuthMethod::PRIVATE_KEY_JWT,
    ]
);

注意:此库中尚未包含JWT生成器。

开发环境

有时您可能需要在您的开发系统上禁用SSL安全性。您可以通过使用false参数调用verify方法来实现。注意:在生产系统上不推荐这样做。

use Maicol07\OpenIDConnect\Client;

$oidc new Client(
    provider_url: 'https://id.example.com',
    client_id: 'ClientIDHere',
    client_secret: 'ClientSecretHere',
    redirect_uri: 'https://example.com/callback.php',
    verify_ssl: false      
);

测试

要运行测试,您需要一个正在运行的OpenID Connect提供者

Keycloak

  1. 运行Keycloak的Docker容器
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:25.0.5 start-dev
  1. 创建一个名为test的领域
  2. 创建一个名为test-client的客户端,其访问类型为confidential
  3. Valid Redirect URIs设置为http://localhost:8080/callback
  4. Web Origins设置为http://localhost:8080
  5. Access Type设置为Bearer-only
  6. Client Authenticator设置为Client id and secret
  7. Client ID设置为test-client
  8. Client Secret设置为test-client-secret
  9. Root URL设置为http://localhost:8080

待办事项

  • 动态注册不支持注册认证令牌和端点

贡献

  • 欢迎提交问题和拉取请求。