rootinc / laravel-saml2-middleware
Saml2 中间件认证
Requires
- php: >=7.3
- laravel/framework: >=5.4.0
- onelogin/php-saml: ^4
This package is auto-updated.
Last update: 2024-08-25 21:53:13 UTC
README
为 Laravel 应用提供 Saml2 认证中间件。如果您喜欢这个,请查看 Laravel Azure 中间件
正常安装
composer require rootinc/laravel-saml2-middleware
- 运行
php artisan vendor:publish --provider="RootInc\LaravelSaml2Middleware\Saml2ServiceProvider"
将配置文件安装到config/saml2.php
- 在我们的路由文件夹中(可能是
web.php
),添加
Route::get('/login/saml2', '\RootInc\LaravelSaml2Middleware\Saml2@saml2'); Route::post('/login/saml2callback', '\RootInc\LaravelSaml2Middleware\Saml2@saml2callback');
- 在我们的
App\Http\Kernel.php
中添加'saml2' => \RootInc\LaravelSaml2Middleware\Saml2::class,
通常添加到$routeMiddleware
数组中。 - 在我们的
.env
中可选地添加SAML2_STRICT, SAML2_SAML2_PROXY_VARS
。如果不添加,这些值将默认为 true。 - 在我们的
.env
中添加SAML2_IDP_ENTITYID, SAML2_IDP_SSO, SAML2_IDP_SLO 和 SAML2_IDP_x509
。 - 在我们的
.env
中可选地添加SAML2_SP_NAME_ID_FORMAT, SAML2_SP_ENTITY_ID, SAML2_SP_SSO, SAML2_SP_SLO, SAML2_SP_x509, SAML2_SP_PRIVATE_KEY
。这些值只有在默认配置不足时才需要覆盖。 - 在我们的
App\Http\Middleware\VerifyCsrfToken.php
中添加'/login/saml2callback' //original saml2 didn't protect anything. Since this is a POST for SAML2, the tokens will of course not match. Thus, we need to ignore
到$except
数组中。 - 将
saml2
中间件添加到任何需要受 auth 保护的路由组中,享受 🎉 - 如果您需要自定义回调,请参阅 扩展安装。
路由
Route::get('/login/saml2', '\RootInc\LaravelSaml2Middleware\Saml2@saml2');
第一个参数可以设置为路由 saml2 登录的位置。 * 根据需要更改。
Route::post('/login/saml2callback', '\RootInc\LaravelSaml2Middleware\Saml2@saml2callback');
第一个参数可以设置为回调后要路由的位置。 * 根据需要更改。
Route::get('/logout/saml2', '\RootInc\LaravelSaml2Middleware\Saml2@saml2logout');
第一个参数可以设置为回调后要路由的位置。 * 根据需要更改。
Route::post('/logout/logoutcallback', '\RootInc\LaravelSaml2Middleware\Saml2@logoutcallback');
第一个参数可以设置为回调后要路由的位置。 * 根据需要更改。
- 注意 - 如果我们更改这些值,请参阅 服务提供者选项覆盖
元数据
从 v0.2.0 版本开始,我们增加了获取元数据的能力。只需添加
Route::get('/saml2/metadata', '\RootInc\LaravelSaml2Middleware\Saml2@saml2metadata');
第一个参数可以设置为路由元数据的位置。 * 根据需要更改。
- 注意 - 如果我们更改这些值,请参阅 服务提供者选项覆盖
扩展安装
默认实现允许您登录用户。但是,假设我们想要将此用户存储到数据库中,以及使用 Laravel Auth 登录用户。建议从 Saml2 类扩展两个回调:success 和 fail。以下提供了如何扩展 Root Laravel Saml2 中间件库的信息
- 要开始(假设我们已遵循 正常安装 指示),在
App\Http\Middleware
文件夹中创建一个名为AppSaml2.php
的文件。您可以通过artisan
或手动完成此操作。 - 将以下内容作为此文件的起点添加
<?php namespace App\Http\Middleware; use RootInc\LaravelSaml2Middleware\Saml2 as Saml2; use Auth; use App\User; class AppSaml2 extends Saml2 { protected function success($request, $token, $profile) { $email = mb_strtolower($profile['Email'][0]); $user = User::updateOrCreate(['email' => $email], [ 'firstName' => $profile['FirstName'][0], 'lastName' => $profile['LastName'][0], ]); Auth::login($user, true); return parent::success($request, $token, $profile); } }
以上提供了一种在成功握手后添加/更新用户的方法。 $profile
包含了我们用于创建或更新用户的各种元数据。默认实现将重定向到目标 URL,或者 /
,因此在这里我们调用父类。您可以自由地不扩展默认实现,并将重定向到其他位置。
- 我们的路由需要更新为以下内容
Route::get('/login/saml2', '\App\Http\Middleware\AppSaml2@saml2'); Route::post('/login/saml2callback', '\App\Http\Middleware\AppSaml2@saml2callback'); Route::get('/logout/saml2', '\App\Http\Middleware\AppSaml2@saml2logout'); Route::post('/logout/logoutcallback', '\App\Http\Middleware\AppSaml2@logoutcallback');
从 v0.2.0 版本开始,如果使用元数据路由,我们需要更新为:Route::get('/saml2/metadata', '\App\Http\Middleware\AppSaml2@saml2metadata');
- 最后,更新
Kernel.php
中的saml2
键为'saml2' => \App\Http\Middleware\AppSaml2::class,
服务提供者选项覆盖
从 v0.2.0 版本开始,我们添加了覆盖服务提供者默认行为的选项。默认设置通常适用于我们的应用程序。然而,配置总是有益的。以下是这些键及其默认值
SAML2_SP_NAME_ID_FORMAT
默认为urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
SAML2_SP_ENTITY_ID
默认为url("/saml2/metadata")
SAML2_SP_SSO
默认为url("/login/saml2callback")
SAML2_SP_SLO
默认为url("/logout/saml2callback")
SAML2_SP_x509
默认为""
SAML2_SP_PRIVATE_KEY
默认为""
如果我们的命名不符合说明书的规范,那么我们应更新 SAML2_SP_ENTITY_ID, SAML2_SP_SSO, SAML2_SP_SLO
的值。
其他扩展选项
每次握手后的回调
Saml2 提供了每次成功请求(握手)后的回调。默认情况下,我们简单地调用 $next
闭包。但是,假设我们想要更新用户。以下是一个示例,说明如何进行更新
<?php namespace App\Http\Middleware; use Closure; use RootInc\LaravelSaml2Middleware\Saml2 as Saml2; use Auth; use Carbon\Carbon; use App\User; class AppSaml2 extends Saml2 { protected function handlecallback($request, Closure $next, $token) { $user = Auth::user(); $user->updated_at = Carbon::now(); $user->save(); return parent::handlecallback($request, $next, $token); } }
基于我们之前的示例(见扩展安装),我们现在在 Auth 中有一个用户(因为我们成功回调中调用了 Auth::login
)。有了用户模型,我们可以更新用户的 updated_at
字段。回调应该调用闭包 $next($request);
并返回它。在我们的例子中,默认实现就是这样做的,所以在这里我们调用父类。
自定义重定向
Saml2 提供了自定义重定向方法的能力。例如,如果会话令牌已过期,但用户仍然通过 Laravel 进行认证,我们可以使用以下示例进行检查
<?php namespace App\Http\Middleware; use RootInc\LaravelSaml2Middleware\Saml2 as Saml2; use Auth; class AppSaml2 extends Saml2 { protected function redirect($request) { if (Auth::user() !== null) { return $this->saml2($request); } else { return parent::redirect($request); } } }
不同的登录路由
Saml2 提供了在中间件中更改 $login_route
的能力。基于扩展安装,在我们的 AppSaml2
类中,我们可以简单地设置 $login_route
为任何值。例如
<?php namespace App\Http\Middleware; use RootInc\LaravelSaml2Middleware\Saml2 as Saml2; class AppSaml2 extends Saml2 { protected $login_route = "/"; }
这将现在将 $login_route
设置为 /
或根目录。
获取/覆盖 Saml2 路由
Saml2 提供了获取 Saml2 URL 的能力。例如,假设我们想要修改 Saml2 URL,使其也将用户的电子邮件作为参数传递给 Saml2。基于扩展安装,在我们的 AppSaml2
类中,我们可以这样做
<?php namespace App\Http\Middleware; use RootInc\LaravelSaml2Middleware\Saml2 as Saml2; use Auth; class AppSaml2 extends Saml2 { //we could overload this if we wanted too. public function getSaml2Url($email = null) { return $this->getAuth()->login(null, [], false, false, true, true, $email); } public function saml2(Request $request) { $user = Auth::user(); $away = $this->getSaml2Url($user ? $user->email : null); return redirect()->away($away); } }
使用 Laravel Saml2 中间件进行测试
我们可以通过调用 actingAs
进行 HTTP 测试或使用 Dusk 的 loginAs
来与 Laravel 的测试集成。这假设我们在成功回调中使用了 Auth::login
方法,如扩展安装中所示。除非我们需要覆盖默认行为,否则在 AppSaml2
类中不需要做任何事情,这将在下面显示
<?php namespace App\Http\Middleware; use RootInc\LaravelSaml2Middleware\Saml2 as Saml2; use Auth; class AppSaml2 extends Saml2 { //this is the default behavior //overwrite to meet your needs protected function handleTesting(Request $request, Closure $next) { $user = Auth::user(); if (!isset($user)) { return $this->redirect($request, $next); } return $this->handlecallback($request, $next, null); } }
上述代码将调用类的 redirect 方法,如果 Laravel 的 auth 中找不到用户。否则,上述代码将调用类的 handlecallback 方法。因此,测试可以检查是否发生了正确的重定向,或者 handlecallback 是否正常工作(默认情况下会调用 $next($request);
)。
贡献
感谢您考虑为 Laravel Saml2 Middleware 贡献!为了鼓励积极的合作,我们鼓励提交拉取请求,而不仅仅是问题。
如果您提交一个问题,问题应包含标题和问题的清晰描述。您还应尽可能提供相关信息和代码示例,以展示问题。问题的目标是让您自己和其他人能够轻松复现错误并开发修复方案。
许可证
Laravel Saml2 Middleware 是开源软件,根据 MIT 许可证 许可。