24slides/laravel-saml2

基于OneLogin工具集的SAML2服务提供商集成到您的Laravel 5.4+应用程序中

2.4.0 2024-04-13 12:57 UTC

README

Latest Stable Version Software License Build Status Quality Score Code Coverage Total Downloads

基于OneLogin 工具集 的SAML2协议集成,用于通过SAML2协议将SSO添加到您的服务。

此包将您的应用程序转换为支持多个身份提供者的服务提供者。

要求

  • Laravel 5.4+
  • PHP 7.0+

入门

安装

步骤 1. 安装依赖项
composer require 24slides/laravel-saml2

如果您使用的是Laravel 5.5及更高版本,服务提供者将自动注册。

对于旧版本,您必须将服务提供者和别名添加到您的 config/app.php

'providers' => [
    ...
    Slides\Saml2\ServiceProvider::class,
]

'alias' => [
    ...
    'Saml2' => Slides\Saml2\Facades\Auth::class,
]
步骤 2. 发布配置文件。
php artisan vendor:publish --provider="Slides\Saml2\ServiceProvider"
步骤 3. 运行迁移。
php artisan migrate

配置

一旦您将 saml2.php 发布到 app/config,您需要配置您的SP。大多数选项都是从 OneLogin Toolkit 继承的,因此您可以查看那里的文档。

身份提供者 (IdP)

为了区分身份提供者,有一个实体称为租户,代表每个IdP。

当请求到达应用程序时,中间件解析UUID并解析租户。

您可以使用以下控制台命令轻松管理租户

  • artisan saml2:create-tenant
  • artisan saml2:update-tenant
  • artisan saml2:delete-tenant
  • artisan saml2:restore-tenant
  • artisan saml2:list-tenants
  • artisan saml2:tenant-credentials

要了解它们的选项,请使用 -h 参数运行命令。

每个租户都有以下属性

  • UUID — 一个唯一的标识符,允许解析租户并相应地配置SP
  • Key — 用于应用程序需要的自定义密钥
  • Entity ID身份提供者实体ID
  • 登录URL — 身份提供者单点登录URL
  • 注销URL — 身份提供者注销URL
  • x509证书 — 以 base64 格式由身份提供者提供的证书
  • 元数据 — 用于您应用程序需要的自定义参数

默认路由

以下路由默认注册

  • GET saml2/{uuid}/login
  • GET saml2/{uuid}/logout
  • GET saml2/{uuid}/metadata
  • POST saml2/{uuid}/acs
  • POST saml2/{uuid}/sls

您可以通过将 saml2.useRoutes 设置为 false 来禁用它们。

可以通过 saml2.routesPrefix 配置参数更改 /saml2 前缀。

用法

认证事件

处理SAML认证的最简单方法是添加 Slides\Saml2\SignedInSlides\Saml2\SignedOut 事件的监听器。

Event::listen(\Slides\Saml2\Events\SignedIn::class, function (\Slides\Saml2\Events\SignedIn $event) {
    $messageId = $event->getAuth()->getLastMessageId();
    
    // your own code preventing reuse of a $messageId to stop replay attacks
    $samlUser = $event->getSaml2User();
    
    $userData = [
        'id' => $samlUser->getUserId(),
        'attributes' => $samlUser->getAttributes(),
        'assertion' => $samlUser->getRawSamlAssertion()
    ];
    
    $user = // find user by ID or attribute
    
    // Login a user.
    Auth::login($user);
});

中间件

要为默认路由定义中间件,将其名称添加到 config/saml2.php

/*
|--------------------------------------------------------------------------
| Built-in routes prefix
|--------------------------------------------------------------------------
|
| Here you may define the prefix for built-in routes.
|
*/

'routesMiddleware' => ['saml'],

然后您需要在 app/Http/Kernel.php 中为您的组定义必要的中间件

protected $middlewareGroups = [
    'web' => [
        ...
    ],
    'api' => [
        ...
    ],
    'saml' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
    ],

注销

用户可以通过两种方式注销

  • 通过在您的应用程序中注销。在这种情况下,您应该先通知IdP,以便它关闭全局会话。
  • 通过注销全局SSO会话。在这种情况下,IdP将在 /saml2/{uuid}/slo 端点通知您(已提供)。

对于第一种情况,调用 Saml2Auth::logout(); 或将用户重定向到路由 saml.logout,它将执行相同的操作。不要立即关闭会话,因为您需要从身份提供者 (IdP) 接收响应确认(重定向)。该响应将由库在 /saml2/sls 处处理,并触发一个事件以完成操作。

对于第二种情况,您将只会收到事件。两种情况都会收到相同的事件。

注意,对于第二种情况,您可能需要手动保存会话以确保注销生效(因为会话是由中间件保存的,但 OneLogin 库会在之前将用户重定向回您的 IdP)

Event::listen('Slides\Saml2\Events\SignedOut', function (SignedOut $event) {
    Auth::logout();
    Session::save();
});

SSO 友好的链接

有时,您需要创建支持 SSO 生命周期的应用程序链接。这意味着您期望在点击该链接后用户会被登录。

最流行的例子是从电子邮件中生成链接,您需要确保当用户从电子邮件访问您的应用程序时,他会自动登录。为了解决这个问题,您可以使用允许您创建 SSO 友好路由和 URL 的辅助函数——saml_url()saml_route()

要生成链接,您需要调用其中一个函数并传递租户的 UUID 作为第二个参数,除非您的会话知道用户已被 SSO 解决。

要基于用户检索 UUID,您应该实现将您的内部用户链接到租户的逻辑。

然后,它会生成如下链接

https://yourdomain/saml/63fffdd1-f416-4bed-b3db-967b6a56896b/login?returnTo=https://yourdomain.com/your/actual/link

基本上,当用户点击链接时,它将启动 SSO 登录过程并将其重定向回所需的 URL。

示例

Azure AD

在此阶段,我们假设您在 Azure AD 上有一个支持单点登录的应用程序。

步骤 1. 获取身份提供者凭证

Azure AD

您需要获取以下参数

  • 登录 URL
  • Azure AD 标识符
  • 注销 URL
  • 证书(Base64)
步骤 2. 创建租户

根据您收到的以下信息,创建租户,如下所示

php artisan saml2:create-tenant \
  --key=azure_testing \
  --entityId=https://sts.windows.net/fb536a7a-7251-4895-a09a-abd8e614c70b/ \
  --loginUrl=https://login.microsoftonline.com/fb536a7a-7251-4895-a09a-abd8e614c70b/saml2 \
  --logoutUrl=https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0 \
  --x509cert="MIIC0jCCAbqgAw...CapVR4ncDVjvbq+/S" \
  --metadata="customer:11235,anotherfield:value" // you might add some customer parameters here to simplify logging in your customer afterwards

成功创建租户后,您将收到以下输出

The tenant #1 (63fffdd1-f416-4bed-b3db-967b6a56896b) was successfully created.

Credentials for the tenant
--------------------------

 Identifier (Entity ID): https://yourdomain.com/saml/63fffdd1-f416-4bed-b3db-967b6a56896b/metadata
 Reply URL (Assertion Consumer Service URL): https://yourdomain.com/saml/63fffdd1-f416-4bed-b3db-967b6a56896b/acs
 Sign on URL: https://yourdomain.com/saml/63fffdd1-f416-4bed-b3db-967b6a56896b/login
 Logout URL: https://yourdomain.com/saml/63fffdd1-f416-4bed-b3db-967b6a56896b/logout
 Relay State: / (optional)
步骤 3. 配置身份提供者

使用以下输出,在应用程序的单点登录设置页面中将参数分配给您的 IdP。

Azure AD

确保您的应用程序可通过 Azure AD 访问

直接从 Azure AD 测试您的应用程序,并确保它可全球访问。

本地运行

如果您想本地测试,您可以使用 ngrok

如果您的应用程序在 URL 创建方面出现问题,您可以通过在 nginx 主机配置文件中添加以下参数来覆盖主机头

fastcgi_param HTTP_HOST your.ngrok.io;
fastcgi_param HTTPS on;

your.ngrok.io 替换为您的实际 ngrok URL

测试

在包文件夹中运行以下操作

vendor/bin/phpunit

安全

如果您发现任何与安全相关的问题,请通过电子邮件 brezzhnev@gmail.com 反馈,而不是使用问题跟踪器。

致谢

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件