vinay-jalalpuram/laravel-saml2-post

这是一个基于OneLogin工具集的Laravel SAML2集成包,作为SP(服务提供者),比simplesamlphp更轻量。

0.16.0 2021-04-27 08:46 UTC

README

Build Status

这是一个基于OneLogin工具集的Laravel SAML2集成包,作为SP(服务提供者)。与simplesamlphp SP相比,它更轻量,安装也更容易。它不需要独立的路由或会话存储即可工作!

该库的目标是尽可能简单。我们不会干扰Laravel用户、认证、会话等。我们更愿意限制自己只完成具体任务。要求用户在IDP处进行认证并处理响应。对于SLO请求也是如此。

安装 - Composer

要安装Saml2作为Composer包用于Laravel 5,只需运行

composer require aherstein/laravel-saml2-post

安装完成后,您可以在config/app.php中的providers数组中注册服务提供者。如果您想的话,可以添加别名saml2

'providers' => [
        ...
    	SamlPost\Saml2\Saml2ServiceProvider::class,
]

'alias' => [
        ...
        'Saml2' => SamlPost\Saml2\Facades\Saml2Auth::class,
]

然后使用php artisan vendor:publish发布配置文件。这将添加app/config/saml2_settings.php文件。此配置几乎由OneLogin直接处理,因此您可以在那里找到更多参考资料,但这里将涵盖真正必要的部分。还有一些关于路由的配置,您可以检查一下,它们相当直接。

配置和设置

.env文件

大多数配置设置存储在您的.env文件中。以下为必需设置

SAML_IDP_HOST=
SAML_IDP_ENTITY_ID=
SAML_IDP_SIGN_ON_URL=
SAML_IDP_SIGN_ON_BINDING=
SAML_IDP_LOG_OUT_URL=
SAML_IDP_LOG_OUT_BINDING=
SAML_IDP_X509CERT=

SAML_SP_X509CERT=
SAML_SP_PRIVATE_KEY=
SAML_SP_NAME_ID_FORMAT=

一旦您将saml2_settings.php发布到自己的文件中,您需要配置您的sp和IDP(远程服务器)。此配置与OneLogin使用的配置之间的唯一真正区别是,SP entityId、断言消费者服务URL和单点登出服务URL由库注入。它们分别来自路由'saml_metadata'、'saml_acs'和'saml_sls'。

请记住,您不需要实现这些路由,但您需要将它们添加到IDP配置中。例如,如果您使用simplesamlphp,请在/metadata/sp-remote.php中添加以下内容

$metadata['http://laravel_url/saml2/metadata'] = array(
    'AssertionConsumerService' => 'http://laravel_url/saml2/acs',
    'SingleLogoutService' => 'http://laravel_url/saml2/sls',
    //the following two affect what the $Saml2user->getUserId() will return
    'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
    'simplesaml.nameidattribute' => 'uid' 
);

您可以通过实际导航到"http://laravel_url/saml2/metadata"来检查这些元数据

确保ConfigServiceProvider正确地注入了IDP的单点登录服务URL设置。

认证守护者

此库支持使用Laravel内置的认证守护者。

将以下内容添加到app/Providers/AuthServiceProvider.phpboot()方法中

    public function boot()
    {
        $this->registerPolicies();
        
        Auth::extend('saml', function ($app, $name, array $config) {
            return new Saml2Guard(Auth::createUserProvider($config['provider']));
        });
        
        Auth::provider('samldriver', function ($app, array $config) {
            return new Saml2UserProvider();
        });

将守护者配置添加到config/auth.php

'guards' => [

...

'saml' => [
    'driver' => 'session',
    'provider' => 'samlusers',
],

'providers' => [

...

'samlusers' => [
    'driver' => 'samldriver',
    'model' => SamlPost\Saml2\Saml2User::class,
],

监听器

请确保在app/Providers/EventServiceProvider.php中注册登录和登出事件监听器

    protected $listen = [
        'SamlPost\Saml2\Events\Saml2LoginEvent' => [
            'App\Listeners\LoginListener',
        ],
        'SamlPost\Saml2\Events\Saml2LogoutEvent' => [
            'App\Listeners\LogoutListener',
        ],
    ];

使用

登录视图

您需要将以下代码包含在名为login的视图中

    <form method="post" action="{{$baseUri}}" accept-charset="utf-8">
        <input type="submit" value="Log In via SSO"/>
        @foreach ($samlParameters as $k => $v)
            <input type="hidden" name="{{$k}}" value="{{$v}}"/>
        @endforeach
    </form>

要启动登录,只需在路由文件中将您想要保护的路径包含在内

Route::middleware(['auth:saml'])->group(function () {
    // Secured routes go here
});

Saml2::login将用户重定向到IDP,并回到库在/saml2/acs处提供的一个端点。这将处理响应并在准备好时触发一个事件。您的下一步是处理该事件,通过向app/Listeners/添加登录和登出事件监听器来处理它。

    public function handle(Saml2LoginEvent $event)
    {
        $user = $event->getSaml2User();
        $auth = $event->getSaml2Auth();

        // Store SAML response data in session
        $this->request->session()->put('isLoggedIn', $auth->isAuthenticated());
        $this->request->session()->put('samlData', $user);
        $this->request->session()->put('user', $user->getAttributes());
    }

登出

现在用户有两种登出的方式。

  • 1 - 在您的应用程序中注销:在这种情况下,您“应该”首先通知IDP以关闭全局会话。
  • 2 - 从全局SSO会话中注销。在这种情况下,IDP将在/saml2/slo端点(已提供)通知您

对于情况1,请调用Saml2Auth::logout();或将用户重定向到路由'saml_logout',该路由执行此操作。不要立即关闭会话,因为您需要从IDP(重定向)接收响应确认。该响应将在/saml2/sls处由库处理,并将触发一个事件以供您完成操作。

对于情况2,您只会接收到事件。情况1和2都会接收到相同的事件。

注意,对于情况2,您可能需要手动保存会话以使注销生效(因为会话由中间件保存,但在发生之前OneLogin库会将您重定向回IDP)

public function handle(Saml2LogoutEvent $event)
{
    // Clear out SAML data from session
    $this->request->session()->put('isLoggedIn', false);
    $this->request->session()->put('samlData', null);
    $this->request->session()->put('user', null);
}

许可证

版权所有(c)2017 Adam Herstein

特此授予任何获得此软件及其相关文档文件(“软件”)副本的任何人,无限制地使用软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许向提供软件的人这样做,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和无侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论这些责任是在合同行为、侵权或其他行为中产生的,与软件或其使用或其他方式相关。