dorelljames/laravel-saml-5.1

为 Laravel 应用程序提供 SAML 支持,使其既能作为 SAML IDP,也能作为 SAML SP。已在 Laravel 5.1 上测试

dev-master 2018-09-11 03:19 UTC

This package is auto-updated.

Last update: 2024-09-05 18:18:19 UTC


README

Laravel-SAML 实现了一个 SAML2 IDP 插件,将 Laravel 转换为 SAML 身份提供者 (IDP)(除常规认证外)。此包旨在与 Laravel 5.1 一起工作。这是从 kingstarter/laravel-saml 的分支,后者旨在用于 Laravel 5.4 或更高版本。虽然尚未在 Laravel 5.2 或 5.3 上测试,但欢迎提交 PR 或您可以直接测试,因为我在 Laravel 5.1 上使它工作所需的工作很少,只需告诉我即可。

此包基于 Dustin Parham 的 Laravel 实现 SAML IDP 指南。为了更好地理解 SAML 的一般概念,请阅读 Cheung 的 Web 开发者 SAML

安装

基本包安装

使用 composer

composer require "dorelljames/laravel-saml-5.1":"dev-master"

Lightsaml 依赖问题

如果您遇到有关 symfony 4(事件调度器)的当前 lightsaml 依赖问题,您可以考虑使用 允许使用 symfony 4 的 lightsaml 分支

Laravel 5.1

将服务提供者添加到 config/app.php

    KingStarter\LaravelSaml\LaravelSamlServiceProvider::class,

配置

有一个配置文件需要发布和需要扩展的 config/filesystem.php 文件。以下命令将发布 config/saml.php 文件。

php artisan vendor:publish --tag="saml_config"

将发布 config/saml.php 文件。

SAML SP 条目

saml.php 配置文件中,需要填充 SAML 服务提供者数组。以下是从 config/saml.php 文件的示例

'sp' => [        
    
    /**
     * Sample SP entry
     * The entry is identified by the base64 encoded URL. This example shows a possible entry for
     * a SimpleSamlPhp service provider running on localhost:
     * 
     * Sample URL:         https:///samlsp/module.php/saml/sp/saml2-acs.php/default-sp
     * Base64 encoded URL: aHR0cHM6Ly9sb2NhbGhvc3Qvc2FtbHNwL21vZHVsZS5waHAvc2FtbC9zcC9zYW1sMi1hY3MucGhwL2RlZmF1bHQtc3A=
     */
    'aHR0cHM6Ly9sb2NhbGhvc3Qvc2FtbHNwL21vZHVsZS5waHAvc2FtbC9zcC9zYW1sMi1hY3MucGhwL2RlZmF1bHQtc3A=' => [
    
        // The destination is the consuming SAML URL. This might be a SamlAuthController receiving the SAML response.  
        'destination' => 'https:///samlsp/module.php/saml/sp/saml2-acs.php/default-sp',
        // Issuer could be anything, mostly it makes sense to pass the metadata URL
        'issuer' => 'https://',
        
        // OPTIONAL: Use a specific audience restriction value when creating the SAMLRequest object.
        //           Default value is the assertion consumer service URL (the base64 encoded SP url). 
        //           This is a bugfix for Nextcloud as SP and can be removed for normal SPs.
        'audience_restriction' => 'https://',
    ],
    
],

您可以使用以下 artisan 命令生成 base_64 编码的 AssertionURL。

   $ php artisan laravel-saml:encodeurl https://sp.webapp.com/saml/login
   --
   URL Given: https://sp.webapp.com/saml/login
   Encoded AssertionURL:aHR0cHM6Ly9zcC53ZWJhcHAuY29tL3NhbWwvbG9naW4=

config/saml.php

'sp' => [        
    
     ...

    /**
     * New entry
     * 
     * Sample URL:         https://sp.webapp.com/saml/login
     * Base64 encoded URL: aHR0cHM6Ly9zcC53ZWJhcHAuY29tL3NhbWwvY29uc3VtZQ==
     */
    'aHR0cHM6Ly9zcC53ZWJhcHAuY29tL3NhbWwvY29uc3VtZQ==' => [
        'destination' => 'https://sp.webapp.com/saml/consume',
        'issuer'      => 'https://sp.webapp.com',
    ],
],

文件系统配置

config/filesystem.php 中需要添加以下条目

    'disks' => [

        ...
        
        'saml' => [
            'driver' => 'local',
            'root' => storage_path().'/saml',
        ],

    ],

此包控制器使用 storage/saml 路径来检索证书和元数据文件。首先创建存储路径,然后添加或链接证书。还需要为 SAML IDP 添加元数据文件。有关生成 IDP metadata.xml 文件的说明,请参阅 https://www.samltool.com/idp_metadata.php

mkdir -p storage/saml/idp
touch storage/saml/idp/{metadata.xml,cert.pem,key.pem}

将内容添加到 IDP 的 metadata.xml、cert.pem 和 key.pem 文件中。

使用 SAML 包

要使用 SAML 包,需要修改一些文件。在您的登录视图中,可能是 resources/views/auth/login.blade.php,在 CSRF 字段下方添加 SAMLRequest 字段(这实际上是一个好地方)

    {{-- The hidden CSRF field for secure authentication --}}
    {{ csrf_field() }}
    {{-- Add a hidden SAML Request field for SAML authentication --}}
    @if(isset($_GET['SAMLRequest']))
        <input type="hidden" id="SAMLRequest" name="SAMLRequest" value="{{ $_GET['SAMLRequest'] }}">
    @endif

SAMLRequest 字段将在收到 http 请求发送的 SAMLRequest 时自动填充,从而启动 SAML 认证尝试。要启动 SAML 认证,需要修改登录和重定向函数。

app/Http/Controllers/Auth/AuthenticatesUsers.php 中分别向 postLoginhandleUserWasAuthenticated 函数添加以下行:(注意:您可能需要将其从 vendor/laravel/framework/src/Illuminate/Foundation/Auth/ 复制到您的 Middleware 目录中)

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Lang;
use Illuminate\Foundation\Auth\RedirectsUsers;

use KingStarter\LaravelSaml\Http\Traits\SamlAuth;

trait AuthenticatesUsers
{
    use RedirectsUsers, SamlAuth;
    
    ...

    public function postLogin(Request $request)
    {
        ...

        // Preserve SAMLRequest when found as login is reattempted
        $loginPath = isset($request['SAMLRequest']) ? $this->loginPath() . "?SAMLRequest=" . urlencode($request['SAMLRequest']) : $this->loginPath();

        return redirect($loginPath)
            ->withInput($request->only($this->loginUsername(), 'remember'))
            ->withErrors([
                $this->loginUsername() => $this->getFailedLoginMessage(),
            ]);
    }
    
    protected function handleUserWasAuthenticated(Request $request, $throttles)
    {
        // Forward request to SAML SP after successful auth
        if (Auth::check() && isset($request['SAMLRequest'])) {
            $this->handleSamlLoginRequest($request);
        }

        ...
    }
    
    ...

要使用 AuthenticatesUsers 特性,我们需要告诉 AuthController 使用它,但它是在 AuthenticatesAndRegistersUsers 特性中使用的。因此,请转到 vendor/laravel/framework/src/Illuminate/Foundation/Auth/ 并将 AuthenticatesAndRegistersUsers.php 复制到 app/Http/Controllers/Auth/AuthenticatesAndRegistersUsers.php

确保您更新命名空间,并使用 use Illuminate\Foundation\Auth\RegistersUsers; 指出 RegistersUsers 的位置。它应该如下所示

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Foundation\Auth\RegistersUsers;

trait AuthenticatesAndRegistersUsers
{
    use AuthenticatesUsers, RegistersUsers {
        AuthenticatesUsers::redirectPath insteadof RegistersUsers;
    }
}

最后,更新 app/Http/Controllers/Auth/AuthController.php 并替换/更新

use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;

use App\Http\Controllers\Auth\AuthenticatesAndRegistersUsers;

为了允许当某人已经登录时直接重定向,我们还需要在 app/Http/Middleware/RedirectIfAuthenticated.php 中添加一些行

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

use KingStarter\LaravelSaml\Http\Traits\SamlAuth;

class RedirectIfAuthenticated
{
    use SamlAuth;
    
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        // If authenticated with SAML Request, forward to SP
        if (Auth::check() && isset($request['SAMLRequest'])) { 
            $this->handleSamlLoginRequest($request);
        }

        if (Auth::guard($guard)->check()) {
            return redirect('/home');
        }
        return $next($request);
    }
}

SAML服务提供商(SPs)

要添加一个或多个服务提供商,请转到 config/saml.php 配置文件,并向下滚动到 'sp' 数组。拥有SAML-SP的登录地址后,添加另一个条目。由于内部解释的原因,URL需要Base64编码。

调试SP条目

如果在接收Base64字符串或评估SAML身份验证请求时遇到问题,可以在配置文件中使用 saml.debug_saml_request 调试设置。

    // Allow debugging within SamlAuth trait to get SP data  
    // during SAML authentication request
    'debug_saml_request' => true,

请确保环境日志变量 APP_LOG_LEVEL 在您的 .env 文件中设置为调试。

致谢

感谢来自kingstarter/laravel-saml的出色包,该包是此包的来源。

问题

请在GitHub上提交问题(dorelljames/laravel-saml)[https://github.com/dorelljames/laravel-saml]