italia/spid-laravel

Laravel SPID 认证包

v2.0.2-beta 2024-08-08 15:34 UTC

README

Join the #spid-laravel channel Get invited SPID on forum.italia.it

Laravel SPID 认证包

CircleCI Codecov PDS Skeleton License

这是一个为基于 Laravel 的 Web 应用程序提供简单 SPID 认证系统的包。

请参阅 变更日志 了解有关版本和破坏性更改的更多信息。

安装

  1. 在安装此包之前,必须在 composer.json 中启用补丁。这是因为需要将 此补丁 应用于 onelogin/php-saml 以实现 SPID 兼容性。

    按照以下方式编辑您的 composer.json

    ...
    "extra": {
       "enable-patching": "true"
    },
    ...

    或者简单地运行

    composer config extra.enable-patching true.

    由于此包仍在测试阶段,必须在 composer.json 中将 minimum-stability 选项设置为 beta,并将 prefer-stable 选项设置为 true

    可以通过以下命令设置这些选项

    composer config minimum-stability beta
    composer config prefer-stable true

    仅限 Windows

    Composer 需要安装 patch 命令(它不是 Windows 的一部分)。要启用它,请 安装 Git,然后向系统路径添加 C:\Program Files\Git\usr\bin 文件夹。

    在第一个稳定版本发布之前,将删除此安装步骤。

  2. 使用 composer 安装此包。

    composer require italia/spid-laravel

  3. 排除此包使用的 URI 从 CSRF 保护,因为身份提供者无法知道它们发送到您路由的 POST 请求中包含哪些 CSRF 令牌。

    在您的 app/Http/Middleware/VerifyCsrfToken.php 中将 '/spid/*' 设置为 $except 数组的一个元素。

    <?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
    
    class VerifyCsrfToken extends Middleware
    {
        /**
         * The URIs that should be excluded from CSRF verification.
         *
         * @var array
         */
        protected $except = [
            '/spid/*'
        ];
    }

配置

使用以下命令发布配置

php artisan vendor:publish --provider="Italia\SPIDAuth\ServiceProvider"

这将创建一个位于您的 config 目录中的 spid-auth.php 文件,您可以在此文件中设置这些选项

服务提供商选项

  • sp_entity_id:服务提供商实体 ID;
  • sp_organization_name:服务提供商组织名称;
  • sp_organization_display_name:服务提供商组织显示名称;
  • sp_organization_url:服务提供商组织 URL;
  • sp_requested_attributes:向身份提供者请求的 SPID 属性。

这些选项必须根据官方 SPID 技术规则 进行设置。

在配置文件中输入的值将在运行时用于生成 SAML 服务提供商元数据。生成的元数据将以 XML 格式在 /spid/metadata 中可用。

绑定

由于 onelogin/php-saml 的限制,仅支持 AssertionConsumerService 端点的 HTTP-POST 绑定以及 SingleLogoutService 端点的 HTTP-Redirect

应用程序选项

  • middleware_group:分配给包路由的中继器组。默认值是web,这是Laravel自带并提供一些常用功能,如会话管理和Cookie。您可以使用数组添加更多中继器,但必须始终包含web
  • routes_prefix:应用于包路由的路由前缀。如果您更改默认的spid值,请确保根据上述说明在app/Http/Middleware/VerifyCsrfToken.php文件中反映此更改。请注意,在此文档中,假设值为spid
  • login_view:当用户被包spid.auth中继器重定向时显示的视图(见下文中继器部分)。默认视图是spid-auth::login-spid
  • after_login_url:成功登录后要重定向到的URL。如果登录过程由包spid.auth中继器触发,用户将被重定向到原始目的地。默认值是/
  • after_logout_url:成功注销后要重定向到的URL。默认值是/

请注意,php artisan vendor:publish --provider="Italia\SPIDAuth\ServiceProvider"命令将一些静态资源复制到您的public目录。您可以在命令行上添加--tag=spid-config--tag=spid-assets选项以单独发布配置和资源。

Cookie

由于SameSite Cookie参数的特定工作模式,此包只能与laxnone策略一起使用。因此,配置选项session.same_site必须相应设置。

用法

SPID身份验证过程对您的应用程序的身份验证系统一无所知。如果您计划将您的身份验证系统集成到SPID,您可以监听LoginEventLogoutEvent(见下文事件示例)。

SPIDAuth服务提供商

如果您需要在应用程序的身份验证逻辑中实现更多自定义,您可以使用SPIDAuth服务提供商中可用的方法。

首先,您需要从服务容器获取服务提供商的实例

$SPIDAuth = app('SPIDAuth');

以下公开方法可以在您的应用程序中使用。

按钮

您可以通过在模板中包含spid-auth::spid-button视图来显示简单的SPID访问按钮

@include('spid-auth::spid-button')

可选地,您可以指定按钮大小(smlxl

@include('spid-auth::spid-button', ['size' => 'm'])

要显示右对齐的按钮下拉菜单,可以将rightAlign参数设置为true

@include('spid-auth::spid-button', ['rightAlign' => true])

您的模板必须在head标签内包含一个@stack('styles')指令,并在body标签内(在SPID访问按钮标记代码之后)包含一个@stack('scripts')指令。

此按钮是官方的spid-sp-access-button,需要jQuery。

场景

  1. 用户点击按钮,显示一组身份提供者;
  2. 用户选择一个身份提供者,并被重定向到相应的登录页面;
  3. 登录成功后,用户将被重定向到在after_login_url选项中指定的URL,并触发一个LoginEvent

中继器

您可以将spid.auth中继器分配给特定的路由,如下所示

Route::get('private', 'PrivateController@show')->middleware('spid.auth');

或者您可以将 spid.auth 中间件分配给应用程序控制器

class PrivateController extends Controller
{
    /**
     * Instantiate a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('spid.auth');
    }
}

场景

  1. 用户请求一个被分配了 spid.auth 中间件的资源。
  2. 用户将被重定向到 /spid/login,并显示在 login_view 选项中指定的视图;
  3. 用户选择一个身份提供者,并被重定向到相应的登录页面;
  4. 登录成功后,用户将被重定向到原始资源的 URL,并触发一个 LoginEvent

事件

LoginEventLogoutEvent 可以被监听以获取有关已验证用户的某些有用信息。这两个事件共享以下方法:

  • getSPIDUser() 返回一个包含在 sp_requested_attributes 选项中指定的属性并由身份提供者返回的 SPIDUser 对象;
  • getIdp() 返回身份提供者的 entityName。

要使用相同的对象监听两个事件,您可以使用一个 事件订阅者 类,该类可以定义如下:

<?php

namespace App\Listeners;

use Italia\SPIDAuth\Events\LoginEvent;
use Italia\SPIDAuth\Events\LogoutEvent;

class SPIDEventSubscriber
{
    /**
     * Handle SPID login events.
     */
    public function onSPIDLogin($event) {
        // $event->getSPIDUser() and $event->getIdp() are available here
        // your application logic goes here
    }

    /**
     * Handle SPID logout events.
     */
    public function onSPIDLogout($event) {
        // $event->getSPIDUser() and $event->getIdp() are available here
        // your application logic goes here
    }

    /**
     * Register the listeners for the subscriber.
     *
     * @param  Illuminate\Events\Dispatcher $events
     */
    public function subscribe($events)
    {
        $events->listen(
          LoginEvent::class, [ SPIDEventSubscriber::class, 'onSPIDLogin' ]
        );

        $events->listen(
          LogoutEvent::class, [ SPIDEventSubscriber::class, 'onSPIDLogout' ]
        );
    }

}

SPIDEventSubscriber 类必须添加到 app/Providers/EventServiceProvider.php 中的 $subscribe 数组。

protected $subscribe = [
    SPIDEventSubscriber::class,
];

SPIDUser 类为在 sp_requested_attributes 选项中指定的属性提供了 <attribute> 属性(例如,对于 name 属性,您会找到一个 SPIDUser->name 属性)。如果属性不可用,则返回 null

注销

只需为用户提供一个指向 /spid/logout 的链接。

场景

  1. 用户点击指向 /spid/logout 的链接;
  2. 注销成功后,用户将被重定向到在 after_logout_url 选项中指定的 URL,并触发一个 LogoutEvent

示例

此包附带一组简单的控制器、视图和路由,可以在全新安装的 Laravel 应用程序中作为示例运行。

要发布所需文件,请运行以下命令:

php artisan spid-auth:example

这将创建以下文件:

  • app/Http/Controllers/HomeController.php
  • app/Http/Controllers/PrivateController.php
  • app/Listeners/SPIDEventSubscriber.php
  • resources/views/layouts/app.blade.php
  • resources/views/home.blade.php
  • resources/views/private.blade.php

接下来,按照上述说明,将 SPIDEventSubscriber 类添加到 app/Providers/EventServiceProvider.php

您可以通过打开 storage/logs/laravel.log 来读取由 SPIDEventSubscriber 记录的一些示例信息。

注意事项

安全

请确保在 app/config/app.php 中设置您的时区,因为每个断言的 ID 都被缓存以防止重放攻击。此功能依赖于应用程序的正确时区配置。

HTTPS

根据 SPID 技术规范 的要求,服务提供商 必须 只接受 HTTPS 中的消息。根据此要求,此包中的一些 cookie 使用 Secure 策略创建,因此在非安全上下文中无法进行身份验证。

测试身份提供者

spid-idps.php 文件中定义了官方的 SPID 身份提供者

为了测试目的,此文件还包括一个测试身份提供者。有关 SPID 认证测试的更多信息,请参阅 SPID 测试环境

您可以使用 config/spid-auth.php 文件中的 test_idp 条目来启用/禁用测试身份提供者。

'test_idp' => [
    'entityId' => '<Test IdP entityId>',
    'sso_endpoint' => '<Test IdP SingleSignOnService endpoint>',
    'slo_endpoint' => '<Test IdP SingleLogoutService endpoint>',
    'x509cert' => '<Test IdP x509 certificate>',
],

'test_idp' => false 设置为禁用.

服务提供商证书和私钥

spid-auth.php 文件中定义了服务提供商的 X.509 证书和私钥。请注意,提供的值仅用于测试目的,不能在生产环境中使用。

您可以在应用程序的 config/spid-auth.php 文件中设置自己的 X.509 证书和私钥(这将覆盖包中的设置)。

证书和私钥可以配置为字符串或文件路径。如果在您的 config/spid-auth.php 中都指定了它们,则字符串指定的将具有优先级。

更改值并保持私钥的秘密.

许可证

除非另有说明,否则通常将 BSD-3-Clause License 应用于本存储库中的所有代码。

根据 此 README 中所述,部分代码受 MIT License 的约束。

Titillium 字体,包括在 CSS 文件中,受 SIL Open Font License 1.1 的约束。

FOSSA Status