cirrusidentity / simplesamlphp-module-authoauth2
OAuth2认证源的SSP模块
Requires
- php: >=7.4 || ^8.0
- ext-json: *
- firebase/php-jwt: ^5.5|^6
- kevinrob/guzzle-cache-middleware: ^4.1.1
- league/oauth2-client: ^2.7
- psr/cache: ^1.0|^2.0|^3.0
- simplesamlphp/composer-module-installer: ^1.1
- simplesamlphp/simplesamlphp: ^v2.0.0
- symfony/cache: ^6.0|^5.0|^4.3|^3.4
Requires (Dev)
- phpunit/phpunit: ^9.5
- psalm/plugin-phpunit: ^0.18.3
- simplesamlphp/simplesamlphp-test-framework: ^1.2
- squizlabs/php_codesniffer: ^3.7
Suggests
- patrickbussmann/oauth2-apple: Used to provide Apple sign in functionality
- dev-master
- v4.1.0-beta.2
- v4.1.0-beta.1
- v4.0.0
- v4.0.0-beta.2
- v4.0.0-beta.1
- v4.0.0-alpha.1
- 3.x-dev
- v3.3.0
- v3.2.0
- v3.1.0
- v3.0.0
- v2.1.0
- v2.0.0
- v1.0.0
- dev-dependabot/github_actions/dot-github/workflows/actions/download-artifact-4.1.7
- dev-bug/update_consent_template
- dev-linkedin_api_version_hdr
- dev-linkedin_oidc
- dev-feature/linkedin_v2
- dev-test_ext_apple_provider
- dev-MS_testing
This package is auto-updated.
Last update: 2024-09-20 16:12:36 UTC
README
SimpleSAMLphp OAuth2认证源模块
这是一个用于对OAuth2或OIDC服务器进行认证的通用模块。它执行authorization_code
流程,然后使用生成的访问令牌查询端点以获取用户的属性。它是围绕优秀的PHP League OAuth2 Client的包装。
SSP 2
SSP2的兼容性工作将在ssp2分支中完成。
SSP作为OIDC服务器
如果您对使用SSP作为OIDC OP感兴趣,请参阅OIDC模块。
目录 由DocToc生成
安装
该模块可以使用composer安装。
composer require cirrusidentity/simplesamlphp-module-authoauth2
如果您使用SSP 2,请使用版本4。如果您使用SSP 1.X,请使用版本3。
或者您可以从master分支安装最新版本
composer require cirrusidentity/simplesamlphp-module-authoauth2:dev-master
如果您将SSP安装到tar包分发的SSP中,那么composer默认还会安装SSP和此模块的所有dev
依赖项。这可能是一个很长的列表。如果您不想安装dev依赖项,则可以使用。
composer require --no-update cirrusidentity/simplesamlphp-module-authoauth2 && composer update --no-dev cirrusidentity/simplesamlphp-module-authoauth2
变更日志
用法
通用OAuth2客户端配置如下
- OAuth2服务器端点
- 客户端密钥/ID
- 可选的scope参数
- 可选的授权URL查询参数
重定向URI
几乎所有的OAuth2/OIDC供应商都会要求您注册重定向URI。使用以下形式的URL,并将主机名、SSP_PATH以及可选地端口设置为正确的值。
https://hostname/SSP_PATH/module.php/authoauth2/linkback.php
供应商特定提示
scope或scopes:可以传递哪些参数?
大多数配置项都通过到provider
实现传递,因此将取决于您选择的供应商。如果您使用authsource authoauth2:OAuth2
而没有覆盖providerClass
,则“通用用法”中的选项将有效。如果您使用authoauth2:OpenIDConnect
,则可用的配置选项集将不同。
scope与scopes:由authoauth2:OAuth2
使用的默认供应商支持设置'scopes' => ['email']
或通过在urlAuthorizeOptions
中设置scope
。其他供应商可能只支持后者(在urlAuthorizeOptions
中设置)。
通用用法
通用用法提供了足够的配置参数,可以与任何OAuth2或OIDC服务器一起使用。
'oauth2' => array( 'authoauth2:OAuth2', // *** Required for all integrations *** 'urlAuthorize' => 'https://www.example.com/oauth2/authorize', 'urlAccessToken' => 'https://www.example.com/oauth2/token', 'urlResourceOwnerDetails' => 'https://api.example.com/userinfo', // You can add query params directly to urlResourceOwnerDetails or use urlResourceOwnerOptions. 'urlResourceOwnerOptions' => [ 'fields' => 'id,name,first_name,last_name,email' ], // allow fields from token response to be query params on resource owner details request 'tokenFieldsToUserDetailsUrl' => [ 'fieldName' => 'queryParamName', 'access_token' => 'access_token', 'user_id' > 'user_id', ], // *** Required for most integrations *** // Test App. 'clientId' => '133972730583345', 'clientSecret' => '36aefb235314bad5df075363b79cbbcd', // *** Optional *** // Custom query parameters to add to authorize request 'urlAuthorizeOptions' => [ 'prompt' => 'always', // The underlying OAuth2 library also supports overriding requested scopes //'scope' => ['other'] ], // Default scopes to request 'scopes' => ['email', 'profile'], 'scopeSeparator' => ' ', // Customize redirect, if you don't want to use the standard /module.php/authoauth2/linkback.php 'redirectUri' => 'https://myapp.example.com/callback', // See League\OAuth2\Client\Provider\GenericProvider for more options // Guzzle HTTP config // Wait up to 3.4 seconds for Oauth2 servers to respond //http://docs.guzzlephp.org/en/stable/request-options.html#timeout 'timeout' => 3.4, // http://docs.guzzlephp.org/en/stable/request-options.html#proxy 'proxy' => [ ], // All attribute keys will have this prefix 'attributePrefix' => 'someprefix.', // Enable logging of request/response. This *will* leak you client secret and tokens into the logs 'logHttpTraffic' => true, //default is false 'logMessageFormat' => 'A Guzzle MessageFormatter format string', // default setting is sufficient for most debugging 'logIdTokenJson' => true, //default false. Log the json in the ID token. ),
OpenID Connect用法
对于支持OpenID Connect发现协议的供应商,配置可以简化一些。只需要提供发行者URL、客户端ID和客户端密钥。
不是所有来自 authoauth2:OAuth2
的配置选项都在 OpenIDConnect
中受支持
'openidconnect' => array( 'authoauth2:OpenIDConnect', // *** Required for all integrations *** 'issuer' => 'https://www.example.com', # e.g https://# 'clientId' => '133972730583345', 'clientSecret' => '36aefb235314bad5df075363b79cbbcd', // Most Optional settings for OAuth2 above can be used // *** Optional *** // Customize post logout redirect, if you don't want to use the standard /module.php/authoauth2/loggedout.php 'postLogoutRedirectUri' => 'https://myapp.example.com/loggedout' // Set a specific discovery url. Default is $issuer/.well-known/openid-configuration 'discoveryUrl' => 'https://login.microsoftonline.com/common/.well-known/openid-configuration', // Check if the issuer in the ID token matches the one from discovery. Default true. For some multi-tenant // applications (for example cross tenant Azure logins) the token issuer varies with tenant 'validateIssuer' => false, // Earlier version OpenIDConnect authsource doesn't support using `scopes` for overriding scope //'urlAuthorizeOptions' => [ // 'scope' => 'openid' //] ),
如果你的 OP 支持前端单点登出,你可以配置 https://hostname/SSP_PATH/module.php/authoauth2/logout.php?authSource=AUTHSOURCE
其中 AUTHSOURCE
是你的 authsource 在 authsources 配置中的 id(如上例中的 openidconnect
)
供应商特定用法
有众多官方和第三方提供商,你可以使用这些提供商而不是通用的 OAuth2 提供商。使用这些提供商之一可以简化配置。
要使用提供商,你必须首先安装它 composer require league/oauth2-some-provider
然后配置它。
'providerExample' => array( // Must install correct provider with: composer require league/oauth2-example 'authoauth2:OAuth2', 'providerClass' => 'League\OAuth2\Client\Provider\SomeProvider', 'clientId' => 'my_id', 'clientSecret' => 'my_secret', ),
模板特定用法
对于某些 OAuth2 提供商,通用的端点配置已经定义在 ConfigTemplate
中。你可以参考这些来减少在 authsource 中需要输入的内容。
'google' => array_merge(\SimpleSAML\Module\authoauth2\ConfigTemplate::GoogleOIDC, [ 'clientId' => '3473456456-qqh0n4b5rrt7vkapgk3e4osre40.apps.googleusercontent.com', 'clientSecret' => 'shhh', 'urlAuthorizeOptions' => [ 'hd' => 'example.com', ], ]),
或者使用模板选项
'providerExample' => array( 'authoauth2:OAuth2', 'template' => 'GoogleOIDC', 'clientId' => 'my_id', 'clientSecret' => 'my_secret', ),
示例
这些示例中有几个展示了如何配置通用端点以验证 Facebook、Amazon 和 Google 等。在许多情况下,你可以从 ConfigTemplate
中使用模板来使配置更简洁,或者你可以使用特定于提供商的 OAuth2 客户端的基本实现。
通用Facebook
你可以使用 Facebook 模板 'template' => 'Facebook',
然后只需提供 clientId
和 clientSecret
以获得更简洁的配置。
'templateFacebook' => [ 'authoauth2:OAuth2', 'template' => 'Facebook', 'clientId' => '13397273example', 'clientSecret' => '36aefb235314baexample', ], 'genericFacebookTest' => array( 'authoauth2:OAuth2', // *** Facebook endpoints *** 'urlAuthorize' => 'https://#/dialog/oauth', 'urlAccessToken' => 'https://graph.facebook.com/oauth/access_token', // Add requested attributes as fields 'urlResourceOwnerDetails' => 'https://graph.facebook.com/me?fields=id,name,first_name,last_name,email', // *** My application *** 'clientId' => '13397273example', 'clientSecret' => '36aefb235314baexample', 'scopes' => 'email', // *** Optional *** // Custom query parameters to add to authorize request 'urlAuthorizeOptions' => [ // Force use to reauthenticate 'auth_type' => 'reauthenticate', ], ),
通用Amazon
'genericAmazonTest' => array( 'authoauth2:OAuth2', // *** Amazon Endpoints *** 'urlAuthorize' => 'https://www.amazon.com/ap/oa', 'urlAccessToken' => 'https://api.amazon.com/auth/o2/token', 'urlResourceOwnerDetails' => 'https://api.amazon.com/user/profile', // *** My application *** 'clientId' => 'amzn1.application-oa2-client.94d04152358dexample', 'clientSecret' => '8681bdd290df87example', 'scopes' => 'profile', ),
通用Google
'genericGoogleTest' => array( 'authoauth2:OAuth2', // *** Google Endpoints *** 'urlAuthorize' => 'https://#/o/oauth2/auth', 'urlAccessToken' => 'https://#/o/oauth2/token', 'urlResourceOwnerDetails' => 'https://www.googleapis.com/oauth2/v3/userinfo', // *** My application *** 'clientId' => '685947170891-exmaple.apps.googleusercontent.com', 'clientSecret' => 'wV0FdFs_example', 'scopes' => array( 'openid', 'email', 'profile' ), 'scopeSeparator' => ' ', ),
供应商特定Google
'googleProvider' => array( // Must install correct provider with: composer require league/oauth2-google 'authoauth2:OAuth2', 'providerClass' => 'League\OAuth2\Client\Provider\Google', 'clientId' => 'client_id', 'clientSecret' => 'secret', ),
调试
HTTP日志记录
你可以使用 logHttpTraffic
标志启用 http 记录,并可选地使用 logMessageFormat
自定义格式。有关如何定义格式字符串的示例,请参阅 Guzzle 的 MessageFormatter
类。
安全提示:启用 http 记录会使你的客户端密钥和任何返回的访问或 id 令牌出现在你的日志中。
使用Curl
你可以使用命令行中的 curl
与 OAuth2/OIDC 服务器交互。
获取代码
第一步是获取一个有效的代码,并确保模块不会尝试使用它。这可以通过构建一个具有无效状态值但所有其他参数都正确的授权 URL 来完成。
如果你使用上述链接登录,它将带你回到你的 SSP 实例,并带有 authorization_code
(你应该捕获)然后你的 SSP 实例将报告一个关于无效状态参数的错误。状态检查在消耗 authorization_code
之前发生,因此你知道 SSP 没有使用它。
获取访问令牌
现在你可以使用代码并尝试获取一个访问令牌
curl -d "code=REPLACE" \ -d "client_secret=my_secret" \ -d "client_id=my_client" \ -d "redirect_uri=https://myapp.example.com/simplesaml/module.php/authoauth2/linkback.php" \ -d 'grant_type=authorization_code' \ https://as.example.com/openid/token
获取用户信息
使用上面的访问令牌调用用户信息端点
curl -H "Authorization: Bearer $ACCESS_TOKEN" https://as.example.com/userInfo
从现有认证模块迁移
如果你正在从现有的认证模块迁移,例如 authfacebook
,你需要执行以下操作之一:
- 将此模块的
authoauth2
重定向 URI 添加到 Facebook 应用中,或者 - 覆盖
authoauth2
authsource 的重定向 URI 以匹配authfacebook
uri(https://myserver.com/module.php/authfacebook/linkback.php
)并执行以下操作之一- 编辑
/modules/authfacebook/www/linkback.php
以有条件地调用OAuth2ResponseHandler
(见下文) - 配置 Apache 重写规则,将 '/module.php/authfacebook/linkback.php' 修改为 '/module.php/authoauth2/linkback.php'
- 符号链接或编辑
/modules/authfacebook/www/linkback.php
以调用/modules/authoauth2/public/linkback.php
- 编辑
一些社交提供商支持多种登录协议,并且旧版 SSP 模块可能使用非 OAuth2 版本进行登录。要迁移到此模块,你可能需要做一些应用程序更改。例如
- LinkedIn 模块使用 oauth1,你可能需要调整你的应用程序以迁移到他们的 oauth2 API
- 从 OpenID 2 Yahoo 登录迁移到 OIDC Yahoo 登录需要创建 Yahoo 应用。
调用OAuth2ResponseHandler
要从现有模块迁移,您可以调整该模块的linkback
或重定向处理程序,使其条件性地使用OAuth2ResponseHandler
。在以下示例中,如果进程是由authoauth2
触发的,则代码将使用authoauth2
,否则使用现有的处理程序。
$handler = new \SimpleSAML\Module\authoauth2\OAuth2ResponseHandler(); if ($handler->canHandleResponse()) { $handler->handleResponse(); return; }
开发
Docker
包含preprodwarning
模块是为了测试authproc过滤器。注意: preprodwarning
的1.0.2版本在重定向URL中存在一个错误。如果使用它,您需要将浏览器URL中的showwarning.php
更改为warning
。
docker run --name ssp-oauth2-dev \
--mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/authoauth2,readonly \
-e STAGINGCOMPOSERREPOS=authoauth2 \
-e COMPOSER_REQUIRE="cirrusidentity/simplesamlphp-module-authoauth2:@dev simplesamlphp/simplesamlphp-module-preprodwarning" \
-e SSP_ADMIN_PASSWORD=secret1 \
-e SSP_ENABLED_MODULES="authoauth2 preprodwarning" \
--mount type=bind,source="$(pwd)/docker/config/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \
--mount type=bind,source="$(pwd)/docker/config/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \
-p 443:443 cirrusid/simplesamlphp:v2.0.7
然后访问(解析为localhost和Docker容器)测试认证源页面以测试一些预配置的社会集成(是的,您可以看到应用程序密码,这些应用程序仅用于此演示)。
Facebook测试用户
预配置的Facebook应用程序只能通过测试账户访问。您必须从Facebook注销,否则您将收到一个错误,说明应用程序未激活。
- 邮箱:open_nzwvghb_user@tfbnw.net
- 密码:SSPisMyFavorite2022
代码风格
运行phpcs
来检查代码样式。
php vendor/bin/phpcs