g2planet/laravel-saml

为Laravel应用提供SAML支持,使其同时成为SAML身份提供者(IDP)和SAML服务提供者(SP)。

1.5 2022-02-11 22:20 UTC

This package is not auto-updated.

Last update: 2024-09-21 11:11:21 UTC


README

为kingstarter/laravel-saml创建的分支已更新,适用于Laravel 6+。

Laravel-SAML实现了一个SAML2 IDP插件,将Laravel转换为一个SAML身份提供者(IDP),除了常规的认证外。

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

安装

基本软件包安装

使用`composer`

composer require "g2planet/laravel-saml":"dev-master"

lightsaml依赖问题

如果你遇到了关于symfony 4(事件调度器)的当前lightsaml依赖问题,你可能需要考虑使用允许使用symfony 4的lightsaml分支

Laravel 5.4

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

    KingStarter\LaravelSaml\LaravelSamlServiceProvider::class,

Laravel 5.5+

此软件包支持Laravel的包自动发现,应在需要时通过composer自动加载。如果软件包未自动发现,则运行

    php artisan package:discover

配置

有一个配置文件需要发布,以及需要扩展的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
        // This is the IDP Entity ID that will be sent to the SP.
        '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://',

        // OPTIONAL: Use to override the default email attribute to set a custom NameID value for a SP
        //           The NameID attribute must be a property on the User model.
        'nameID' => 'username',
    ],
    
],

您可以使用以下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元数据.xml文件的说明,请参阅https://www.samltool.com/idp_metadata.php

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

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

使用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字段将在接收到SAMLRequest的http请求时自动填写,并因此启动SAML认证尝试。为了启动SAML认证,需要修改登录和重定向函数。在`app/Http/Middleware/AuthenticatesUsers.php`中,在顶部和authenticated函数中添加以下行:(注意:您可能需要将其从vendor/laravel/framework/src/Illuminate/Foundation/Auth/复制到您的中间件目录中)

<?php

namespace App\Http\Middleware;

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

use KingStarter\LaravelSaml\Http\Traits\SamlAuth;

trait AuthenticatesUsers
{
    use RedirectsUsers, ThrottlesLogins, SamlAuth;
    
    ...

    protected function authenticated(Request $request, $user)
    {
        if(Auth::check() && isset($request['SAMLRequest'])) {
            $this->handleSamlLoginRequest($request);
        }
    }
    
    ...

为了允许以后在有人已经登录的情况下直接重定向,我们还需要在`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
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        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`文件中设置为调试模式。