jumbojett / openid-connect-php
基本的OpenID Connect客户端
v1.0.2
2024-09-13 07:08 UTC
Requires
- php: >=7.0
- ext-curl: *
- ext-json: *
- phpseclib/phpseclib: ^3.0.7
Requires (Dev)
- phpunit/phpunit: <10
- roave/security-advisories: dev-latest
- yoast/phpunit-polyfills: ^2.0
This package is not auto-updated.
Last update: 2024-09-13 07:09:54 UTC
README
这是一个简单的库,允许应用程序通过基本的OpenID Connect流程进行用户身份验证。这个库希望通过使其足够简单,以便对OpenID Connect协议了解不多的开发者也能设置身份验证来鼓励使用OpenID Connect。
特别感谢Justin Richer和Amanda Anganes对协议的帮助和支持。
要求
- PHP 7.0或更高版本
- CURL扩展
- JSON扩展
安装
- 使用composer安装库
composer require jumbojett/openid-connect-php
- 包含composer自动加载器
require __DIR__ . '/vendor/autoload.php';
示例 1: 基本客户端
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', 'ClientSecretHere'); $oidc->setCertPath('/path/to/my.cert'); $oidc->authenticate(); $name = $oidc->requestUserInfo('given_name');
示例 2: 动态注册
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient("https://id.provider.com"); $oidc->register(); $client_id = $oidc->getClientID(); $client_secret = $oidc->getClientSecret(); // Be sure to add logic to store the client id and client secret
示例 3: 网络和安全
// Configure a proxy $oidc->setHttpProxy("http://my.proxy.com:80/"); // Configure a cert $oidc->setCertPath("/path/to/my.cert");
示例 4: 请求客户端凭据令牌
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', 'ClientSecretHere'); $oidc->providerConfigParam(['token_endpoint'=>'https://id.provider.com/connect/token']); $oidc->addScope(['my_scope']); // this assumes success (to validate check if the access_token property is there and a valid JWT) : $clientCredentialsToken = $oidc->requestClientCredentialsToken()->access_token;
示例 5: 请求资源所有者令牌(带客户端认证)
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', 'ClientSecretHere'); $oidc->providerConfigParam(['token_endpoint'=>'https://id.provider.com/connect/token']); $oidc->addScope(['my_scope']); //Add username and password $oidc->addAuthParam(['username'=>'<Username>']); $oidc->addAuthParam(['password'=>'<Password>']); //Perform the auth and return the token (to validate check if the access_token property is there and a valid JWT) : $token = $oidc->requestResourceOwnerToken(TRUE)->access_token;
示例 6: 隐式流的简单客户端,例如Azure AD B2C(见http://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth)
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', 'ClientSecretHere'); $oidc->setResponseTypes(['id_token']); $oidc->setAllowImplicitFlow(true); $oidc->addAuthParam(['response_mode' => 'form_post']); $oidc->setCertPath('/path/to/my.cert'); $oidc->authenticate(); $sub = $oidc->getVerifiedClaims('sub');
示例 7: 访问令牌的 introspection(见https://tools.ietf.org/html/rfc7662)
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', 'ClientSecretHere'); $data = $oidc->introspectToken('an.access-token.as.given'); if (!$data->active) { // the token is no longer usable }
示例 8: PKCE客户端
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', null); $oidc->setCodeChallengeMethod('S256'); $oidc->authenticate(); $name = $oidc->requestUserInfo('given_name');
示例 9: 后端通道注销
后端通道身份验证假设您可以在服务器端代表用户结束会话(而不依赖于他们的浏览器)。请求是从OP直接到您的RP的POST请求。通过这种方式,即使用户没有在浏览器或其他设备上打开您的RP,但仍然在那里有一个活跃的会话,使用这个库可以确保您的RP为用户执行“单点登出”。
sid或sub可能可以通过从OP发送的注销令牌访问。如果有助于将其与一个会话匹配以销毁它,您可以使用getSidFromBackChannel()
或getSubjectFromBackChannel()
检索它们。
以下确保使用此库验证后端通道注销令牌,但之后只是假设找到这样一个会话并销毁它的方法。根据您RP的需求进行调整。
function handleLogout() { // NOTE: assumes that $this->oidc is an instance of OpenIDConnectClient() if ($this->oidc->verifyLogoutToken()) { $sid = $this->oidc->getSidFromBackChannel(); if (isset($sid)) { // Somehow find the session based on the $sid and // destroy it. This depends on your RP's design, // there is nothing in the OIDC spec to mandate how. // // In this example, we find a Redis key, which was // previously stored using the sid we obtained from // the access token after login. // // The value of the Redis key is that of the user's // session ID specific to this hypothetical RP app. // // We then switch to that session and destroy it. $this->redis->connect('127.0.0.1', 6379); $session_id_to_destroy = $this->redis->get($sid); if ($session_id_to_destroy) { session_commit(); session_id($session_id_to_destroy); // switches to that session session_start(); $_SESSION = []; // effectively ends the session } } } }
示例 10: 启用令牌端点认证方法
默认情况下,客户端侧仅启用client_secret_basic
,这在很长一段时间内是唯一受支持的。最近添加了client_secret_jwt
和private_key_jwt
,但它们默认是禁用的,直到明确启用。
use Jumbojett\OpenIDConnectClient; $oidc = new OpenIDConnectClient('https://id.provider.com', 'ClientIDHere', null); # enable 'client_secret_basic' and 'client_secret_jwt' $oidc->setTokenEndpointAuthMethodsSupported(['client_secret_basic', 'client_secret_jwt']); # for 'private_key_jwt' in addition also the generator function has to be set. $oidc->setTokenEndpointAuthMethodsSupported(['private_key_jwt']); $oidc->setPrivateKeyJwtGenerator(function(string $token_endpoint) { # TODO: what ever is necessary })
开发环境
在某些情况下,您可能需要在您的开发系统上禁用SSL安全。注意:这不建议在生产系统上使用。
$oidc->setVerifyHost(false); $oidc->setVerifyPeer(false);
此外,您的本地系统可能不支持HTTPS,因此您可能需要禁用升级到它
$oidc->setHttpUpgradeInsecureRequests(false);
待办事项
- 动态注册不支持注册认证令牌和端点
贡献
- 一旦合并,所有拉取请求都应添加到CHANGELOG.md文件中。