clissmancamacho/php-openid-connect-client

OAuth2/OpenID Connect 客户端库

v0.3.3 2022-04-10 12:16 UTC

This package is auto-updated.

Last update: 2024-09-12 20:41:10 UTC


README

Dependency Status

库的目的是提供工具和构建块,用于创建基于 OAuth2 协议的客户端,并侧重于 OpenID Connect 规范的授权/认证委托。

功能

  • 灵活和可扩展
  • 依赖注入方法
  • 覆盖单元测试
  • 基于 Zend Framework 2 的部分

兼容性

库已经与以下身份提供者进行了测试并成功

要求

  • Zend Framework >= 2.2.1

文档

安装

使用 composer

将以下要求添加到您的 composer.json 文件中

"require":  {
	"ivan-novakov/php-openid-connect-client": "dev-master"
}

不使用 composer

只需克隆存储库或下载并解压最新的 版本,并相应地配置您的自动加载器。

基本用法

您需要一个在身份提供者处注册的 client_idclient_secret,并且您必须知道提供者端点的 URL。

最常用的流程是

  1. 生成授权请求 URL
  2. 将用户重定向到授权 URL 或让用户点击“登录”按钮
  3. 处理回调请求并检索授权代码
  4. 使用授权代码进行令牌请求并检索访问令牌
  5. (可选) 使用访问令牌进行用户信息请求并检索有关用户的信息

库引入了一个“流程”对象,将上述操作整合为两个调用

  • getAuthorizationRequestUri - 生成用户授权的 URL,然后由开发者决定如何将用户重定向到该 URL
  • process - 一次性执行上述列表中的 3、4 和 5 个操作

简单示例

use InoOicClient\Flow\Basic;

$config = array(
    'client_info' => array(
        'client_id' => '<client ID>',
        'redirect_uri' => '<redirect URI>',
        
        'authorization_endpoint' => 'https://#/o/oauth2/auth',
        'token_endpoint' => 'https://#/o/oauth2/token',
        'user_info_endpoint' => 'https://www.googleapis.com/oauth2/v1/userinfo',
        
        'authentication_info' => array(
            'method' => 'client_secret_post',
            'params' => array(
                'client_secret' => '<client secret>'
            )
        )
    )
);

$flow = new Basic($config);

if (! isset($_GET['redirect'])) {
    try {
        $uri = $flow->getAuthorizationRequestUri('openid email profile');
        printf("<a href=\"%s\">Login</a>", $uri);
    } catch (\Exception $e) {
        printf("Exception during authorization URI creation: [%s] %s", get_class($e), $e->getMessage());
    }
} else {
    try {
        $userInfo = $flow->process();
    } catch (\Exception $e) {
        printf("Exception during user authentication: [%s] %s", get_class($e), $e->getMessage());
    }
}

分发器

“流程”对象只是一个外观。真正的“工作”是由所谓的“分发器”完成的

  • InoOicClient\Oic\Authorization\Dispatcher - 生成授权请求 URI 并处理回调请求
  • InoOicClient\Oic\Token\Dispatcher - 发送令牌请求
  • InoOicClient\Oic\UserInfo\Dispatcher - 发送用户信息请求

HTTP 客户端

库使用 Zend Framework 2 HTTP 客户端与 cURL 连接适配器,它提供了最佳的安全性能,特别是关于安全的 HTTPS 连接。HTTP 客户端通过工厂创建,默认情况下配置客户端验证服务器证书。客户端还执行 CN 匹配验证。您可以在 此博客文章 中找到有关使用 Zend Framework 2 的安全 HTTPS 连接的更多信息。

然而,您也可以注入配置不同的 HTTP 客户端实例。

客户端认证

根据 OpenID Connect 规范(另见 OAuth2 规范),库支持以下客户端认证方法

  • client_secret_basic - 客户端密钥以 Authorization HTTP 头的形式发送
  • client_secret_post - 客户端密钥作为POST参数发送

状态持久化

规范建议在请求授权时使用 state 参数。服务器随后必须返回相同的值。这可以防止跨站请求伪造攻击。

库自动处理状态

  1. 在创建授权URI期间生成一个不透明的状态值
  2. 将状态保存在用户会话中
  3. 检查从服务器发送的状态值与保存的状态值是否一致

默认情况下,生成的状态值保存在用户会话中(来自Zend框架的会话容器)。可以通过实现 InoOicClient\Oic\Authorization\State\Storage\StorageInterface 使用其他存储。

高级使用

如果您需要构建自定义流程或扩展/修改某些功能,您可以实现自己的流程对象(有关详细信息,请参阅 InoOicClient\Flow\Basic),或者您可以直接使用分发器。然后,您可以构建和配置相关的对象(分发器、请求、响应等),以满足您的使用场景。

创建客户端信息对象

use InoOicClient\Client\ClientInfo;

$clientOptions = array(
    'client_id' => '<client ID>',
    'redirect_uri' => '<redirect URI>',
    
    'authorization_endpoint' => 'https://#/o/oauth2/auth',
    'token_endpoint' => 'https://#/o/oauth2/token',
    'user_info_endpoint' => 'https://www.googleapis.com/oauth2/v1/userinfo',
    
    'authentication_info' => array(
        'method' => 'client_secret_post',
        'params' => array(
            'client_secret' => '<client secret>'
        )
    )
);

$clientInfo = new ClientInfo();
$clientInfo->fromArray($clientOptions);

准备授权请求URI

use InoOicClient\Oic\Authorization;

$stateManager = new Manager();

$dispatcher = new Authorization\Dispatcher();
$dispatcher->setStateManager($stateManager);

$request = new Authorization\Request($clientInfo, 'code', 'openid profile email');
$uri = $dispatcher->createAuthorizationRequestUri($request);

从回调中检索授权码

$stateManager = new Manager();

$dispatcher = new Authorization\Dispatcher();
$dispatcher->setStateManager($stateManager);

$response = $dispatcher->getAuthorizationResponse();
printf("OK<br>Code: %s<br>State: %s<br>", $response->getCode(), $response->getState());

执行令牌请求

$httpClientFactory = new Http\ClientFactory();
$httpClient = $httpClientFactory->createHttpClient();

$tokenDispatcher = new Token\Dispatcher($httpClient);

$tokenRequest = new Token\Request();
$tokenRequest->setClientInfo($clientInfo);
$tokenRequest->setCode($authorizationCode);
$tokenRequest->setGrantType('authorization_code');

$tokenResponse = $tokenDispatcher->sendTokenRequest($tokenRequest);
printf("Access token: %s<br>", $tokenResponse->getAccessToken());

TODO

  • 为不同的提供者提供用户友好的演示
  • 添加对JWT和ID令牌验证的支持

规范

OpenID Connect

OAuth2

提供者文档

许可

作者