aherstein/laravel-saml2-post

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

0.15.0 2018-02-05 22:55 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、assertionConsumerService URL和singleLogoutService 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.php中的boot()方法

    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

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

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

软件按“原样”提供,除非另有说明,否则不提供任何形式的保证,无论是明示的、暗示的还是其他形式的,包括但不限于适销性、特定目的适用性和非侵权性保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担责任,无论是基于合同、侵权或其他方式,源于、由或与软件或软件的使用或其他交易有关。