ivan-novakov / php-openid-connect-client
OAuth2/OpenID Connect 客户端库
Requires
- php: >=5.3.3
- zendframework/zend-eventmanager: >=2.2.1
- zendframework/zend-filter: >=2.2.1
- zendframework/zend-http: >=2.2.1
- zendframework/zend-json: >=2.2.1
- zendframework/zend-session: >=2.2.1
- zendframework/zend-stdlib: >=2.2.1
Requires (Dev)
- phpunit/phpunit: ~4.4
This package is not auto-updated.
Last update: 2024-09-25 12:20:31 UTC
README
该库的目的是提供基于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_id
和client_secret
。您还必须知道提供者端点的URL。
最常用的流程是
- 生成授权请求URL
- 将用户重定向到授权URL或让他们点击“登录”按钮
- 处理回调请求并检索授权代码
- 使用授权代码发起令牌请求并检索访问令牌
- (可选) 使用访问令牌发起用户信息请求并检索有关用户的信息
该库引入了一个“flow”对象,它将上述操作整合为仅两个调用
getAuthorizationRequestUri
- 生成用户授权的URL,然后由开发者决定如何将用户重定向到该URLprocess
- 一次性执行上述列表中的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());
}
}
分发器
“flow”对象只是一个门面。真正的“工作”是由所谓的“分发器”完成的
InoOicClient\Oic\Authorization\Dispatcher
- 生成授权请求URI并处理回调请求InoOicClient\Oic\Token\Dispatcher
- 发送令牌请求InoOicClient\Oic\UserInfo\Dispatcher
- 发送用户信息请求
HTTP客户端
该库使用带有cURL连接适配器的Zend Framework 2 HTTP客户端,这提供了关于安全HTTPS连接的最佳安全性。通过工厂创建客户端,默认情况下配置客户端以验证服务器证书。客户端还执行CN匹配验证。您可以在此博客文章中找到更多有关使用Zend Framework 2的HTTPS连接的信息。
但是,您可以将配置不同的HTTP客户端的实例注入其中。
客户端认证
根据OpenID Connect规范(另见OAuth2规范),该库支持以下客户端认证方法
client_secret_basic
- 客户端密钥作为Authorization
HTTP头发送client_secret_post
- 客户端密钥以POST参数形式发送
状态持久化
规范建议在请求授权时使用state
参数。服务器随后必须返回相同的值在回调中。这可以防止跨站请求伪造攻击。
库自动处理状态
- 在创建授权URI时生成一个不透明的状态值
- 将状态保存在用户会话中
- 检查从服务器发送的状态值与保存的值是否一致
默认情况下,生成的状态值保存在用户会话中(来自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());
待办事项
- 为不同提供商提供用户友好的示例
- 添加对JWT和ID令牌验证的支持
规范
OpenID Connect
OAuth2