beedooedtech / beedoo-saml2
SAML2 服务提供商 for Laravel Socialite
Requires
- php: ^7.4 || ^8.0
- ext-json: *
- litesaml/lightsaml: ^3.0
- socialiteproviders/manager: ~4.0
This package is auto-updated.
Last update: 2024-09-08 20:05:09 UTC
README
composer require socialiteproviders/saml2
安装 & 基本用法
请参阅基本安装指南,然后按照以下特定提供商的说明进行操作。
注意关于SAML 协议的部分。
将配置添加到config/services.php
可以使用这些配置身份提供者方法的任何一种。如果您的 IDP 支持它,强烈建议使用元数据 URL,这样在 IDP 端的证书轮换就不会造成任何服务中断。
使用身份提供者元数据 URL
'saml2' => [ 'metadata' => 'https://idp.co/metadata/xml', ],
使用身份提供者元数据 XML 文件
'saml2' => [ 'metadata' => file_get_contents('/path/to/metadata/xml'), ],
提供程序将自动选择您的元数据中的第一个 IdP 描述符。如果您的元数据包含多个描述符,您可以通过同时使用metadata
和entityid
配置选项来选择要使用的描述符。
使用身份提供者元数据 URL,选择特定的描述符
'saml2' => [ 'metadata' => 'https://idp.co/metadata/xml', 'entityid' => 'http://saml.to/trust', ],
使用证书字符串手动配置身份提供者
'saml2' => [ 'acs' => 'https://idp.co/auth/acs', // (the IDP's 'Assertion Consumer Service' URL. Also known as the assertion callback URL or SAML assertion consumer endpoint) 'entityid' => 'http://saml.to/trust', // (the IDP's globally unique "Entity ID", normally formatted as a URI, but it is not a real URL) 'certificate' => 'MIIC4jCCAcqgAwIBAgIQbDO5YO....', // (the IDP's assertion signing certificate) ],
使用证书文件手动配置身份提供者
'saml2' => [ 'acs' => 'https://idp.co/auth/acs', 'entityid' => 'http://saml.to/trust', 'certificate' => file_get_contents('/path/to/certificate.pem'), ],
添加提供者事件监听器
配置包的监听器以监听SocialiteWasCalled
事件。
将事件添加到app/Providers/EventServiceProvider
中的listen[]
数组。有关详细说明,请参阅基本安装指南。
protected $listen = [ \SocialiteProviders\Manager\SocialiteWasCalled::class => [ // ... other providers \SocialiteProviders\Saml2\Saml2ExtendSocialite::class.'@handle', ], ];
用法
现在您应该能够像通常使用 Socialite 一样使用此提供程序(假设您已安装了外观)
以启动认证流程
Route::get('/auth/redirect', function () { return Socialite::driver('saml2')->redirect(); });
接收回调
Route::get('/auth/callback', function () { $user = Socialite::driver('saml2')->user(); });
SAML 协议
为了与 Socialite 和 Laravel 最大限度地兼容,Saml2 提供程序默认使用 GET 路由进行认证回调。或者,在 SAML 术语中,它使用服务提供者断言消费者 URL 上的 HTTP-Redirect
绑定
Route::get('/auth/callback', function () { $user = Socialite::driver('saml2')->user(); });
虽然这符合 Socialite 的操作方式,但它不是最常见的 SAML 回调样式,许多身份提供者都不支持它。正常的方法是使用 HTTP-POST
绑定,Saml2 也支持它。要使用此方法,只需将您的 Laravel 路由定义为 POST
路由即可
Route::post('/auth/callback', function () { $user = Socialite::driver('saml2')->user(); });
但是,请注意,这不兼容 Laravel 默认在 routes/web.php
文件中执行的 POST
路由的 CSRF 过滤。为了使此回调样式工作,您可以将此路由定义在 web.php
之外,或者将其添加到您的 VerifyCsrfToken
HTTP 中间件的异常中。
如果您添加了两个路由以支持两种绑定方法,您可以在 config/services.php
中选择默认值,如下所示
'saml2' => [ 'sp_default_binding_method' => \LightSaml\SamlConstants::BINDING_SAML2_HTTP_POST, ],
无状态
提供程序支持 SAML2 无请求/IdP 初始化请求。要使用此技术,必须将 回调 路由设置为无状态的。
Route::get('/auth/callback', function () { $user = Socialite::driver('saml2')->stateless()->user(); });
(请注意,这与标准 Socialite 使用不同,其中标记为无状态的 重定向)
单点登出
警告!请注意,SAML2 单点登出功能是集中登出的最佳尝试方式。在当前情况下,它需要特殊条件才能工作。您必须将您的会话配置为 same_site = 'none'
和 secure = true
才能使其生效,这具有严重的安全影响。在使用此功能之前,请务必了解风险。
您可以通过添加一个用于注销用户并生成SAML2注销响应的GET路由来在您的服务提供商上启用SingleLogoutService。
Route::get('/auth/saml2/logout', function () { $response = Socialite::driver('saml2')->logoutResponse(); });
要发布您的服务提供商的元数据中的SingleLogoutService,您还必须在config/services.php
中配置路由,如下所示:
'saml2' => [ 'sp_sls' => 'auth/saml2/logout', ],
签名和加密
SAML2支持消息和声明的签名和加密。许多身份提供者强制要求其中一个或两个。要启用此功能,您可以为您的应用程序生成一个证书,并在config/services.php
中提供它:
'saml2' => [ 'sp_certificate' => file_get_contents('path/to/sp_saml.crt'), 'sp_private_key' => file_get_contents('path/to/sp_saml.pem'), 'sp_private_key_passphrase' => 'passphrase to your private key, provide it only if you have one', 'sp_sign_assertions' => true, // or false to disable assertion signing ],
sp_private_key_passphrase
是可选的,如果私钥未加密,则不应提供。
始终保护您的私钥,并将其存储在一个不会被公众访问的地方。
使用openssl生成证书和私钥的示例命令:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout sp_saml.pem -out sp_saml.crt
验证
提供者验证声明中的时间戳,包括NotBefore
和NotOnOrAfter
。默认时钟偏差是120秒,但这可以作为配置的一部分进行更改。
'saml2' => [
'metadata' => 'https://idp.co/metadata/xml',
'validation' => [
'clock_skew' => 30, // Time in seconds
],
],
提供者检查身份提供者不会重复一个断言ID。默认情况下,ID会被永久记住,但这可以配置。
'saml2' => [
'metadata' => 'https://idp.co/metadata/xml',
'validation' => [
'repeated_id_ttl' => 365 * 24 * 60 * 60, // Time in seconds, or null to cache forever
],
],
身份提供者元数据
当使用身份提供者的元数据URL时,默认情况下,检索到的元数据会缓存24小时。要修改此生存时间值,请在config/services.php
中使用'ttl'键。
'saml2' => [ 'metadata' => 'https://idp.co/metadata/xml', 'ttl' => 3600, // TTL in seconds ],
要程序化清除缓存,您可以使用:
Socialite::driver('saml2')->clearIdentityProviderMetadataCache();
元数据每24小时检索一次,但如果检索失败,则之前检索到的元数据将用于接下来的24小时。如果元数据的第一次检索失败,则会抛出GuzzleException
。
服务提供者元数据
为了简化在身份提供者侧配置您的Laravel服务提供者,您可以在一个路由上公开服务提供者的XML元数据。
Route::get('/auth/saml2/metadata', function () { return Socialite::driver('saml2')->getServiceProviderMetadata(); });
请注意,您的Laravel服务的断言消费者服务URL已填充到元数据中,因此必须将其设置在config/services.php
中的sp_acs
键中,如果它不是Socialite默认的'/auth/callback'。
例如,如果这是您的回调路由:
Route::get('/auth/saml2/callback', function () { $user = Socialite::driver('saml2')->user(); });
ACS路由应在config/services.php
中配置为:
'saml2' => [ 'metadata' => 'https://idp.co/metadata/xml', 'sp_acs' => 'auth/saml2/callback', ],
服务提供者的默认实体ID是到'/auth/saml2'的URL(例如https://your.domain.com/auth/saml2
),如果需要,可以在config/services.php
中手动配置,如下所示:
'saml2' => [ 'metadata' => 'https://idp.co/metadata/xml', 'sp_entityid' => 'https://my.domain.com/my/custom/entityid', ],
服务提供者的实体ID和断言消费者URL也可以通过以下方式程序化检索:
Socialite::driver('saml2')->getServiceProviderEntityId() Socialite::driver('saml2')->getServiceProviderAssertionConsumerUrl()
您还可以通过在config/services.php
中配置它们,在元数据中发布服务提供商的组织和技术支持联系信息:
'saml2' => [ 'sp_tech_contact_surname' => 'Doe', 'sp_tech_contact_givenname' => 'John', 'sp_tech_contact_email' => 'john.doe@example.com', 'sp_org_lang' => 'en', 'sp_org_name' => 'Example Corporation Ltd.', 'sp_org_display_name' => 'Example Corporation', 'sp_org_url' => 'https://corp.example', ],
如果您想包括这些信息,您必须至少配置组织要包含的sp_org_name
,以及要包含的联系人的sp_tech_contact_email
。默认的sp_org_lang
为英语(en
)。
当配置服务提供者证书时,签名和加密证书会自动包含在元数据中。
用户属性和Name ID
根据SAML惯例,由身份提供者发送的“Name ID”用作回调中返回的User
类实例的ID。
来自'http://schemas.xmlsoap.org/...'和'urn:oid:...'命名空间中知名SAML属性映射到name
、email
、first_name
、last_name
和upn
在User
类中。
身份提供者返回的所有其他属性都存储在User
类的"raw"属性中,并且可以通过$user->getRaw()
检索。
可以通过在config/services.php
中提供一个部分/完整自定义映射来扩展/覆盖默认映射。
'saml2' => [ 'attribute_map' => [ // Add mappings as 'mapped_name' => 'saml_attribute' or 'mapped_name' => ['saml_attribute', ...], for example: 'email' => [ \SocialiteProviders\Saml2\OasisAttributeNameUris::MAIL, \LightSaml\ClaimTypes::EMAIL_ADDRESS, ], 'phone' => \SocialiteProviders\Saml2\OasisAttributeNameUris::PHONE, ], ],
整个断言也存储在 User
实例中,可以通过 $user->getAssertion()
获取。