基于简单的 OneLogin 工具包,用作 SP (服务提供者) 的 Laravel 5 包,用于集成 Saml2
This project is no longer maintained. I'd be glad to transfer ownership, or otherwise you can easily replace it by some of the many forks (let me know if someone wants to list theirs here, or some oher library). The library itself shouldn't change much, but there are occational changes needed to keep up with Laravel and PHP version updates
A Laravel package for Saml2 integration as a SP (service provider) based on OneLogin toolkit, which is much lighter and easier to install than simplesamlphp SP. It doesn't need separate routes or session storage to work!
The aim of this library is to be as simple as possible. We won't mess with Laravel users, auth, session... We prefer to limit ourselves to a concrete task. Ask the user to authenticate at the IDP and process the response. Same case for SLO (Single Logout) requests.
You can install the package via composer:
composer require aacotroneo/laravel-saml2
Or manually add this to your composer.json:
composer.json
"aacotroneo/laravel-saml2": "*"
If you are using Laravel 5.5 and up, the service provider will automatically get registered.
For older versions of Laravel ( [ ... Aacotroneo\Saml2\Saml2ServiceProvider::class, ]
…
php 'idpNames' => ['mytestidp1', 'test', 'myidp2'],
…
env SAML2_mytestidp1_SP_x509="..." SAML2_mytestidp1_SP_PRIVATEKEY="..." // Other SAML2_mytestidp1_* values
SAML2_myidp2_SP_x509="..." SAML2_myidp2_SP_PRIVATEKEY="..." // Other SAML2_myidp2_* values
…
php $metadata['http(s)://{laravel_url}/mytestidp1/metadata'] = array( 'AssertionConsumerService' => 'http(s)://{laravel_url}/mytestidp1/acs', 'SingleLogoutService' => 'http(s)://{laravel_url}/mytestidp1/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' );
…
php public function handle($request, Closure $next) { if ($this->auth->guest()) { if ($request->ajax()) { return response('Unauthorized.', 401); // Or, return a response that causes client side js to redirect to '/routesPrefix/myIdp1/login' } else { $saml2Auth = new Saml2Auth(Saml2Auth::loadOneLoginAuthFromIpdConfig('mytestidp1')); return $saml2Auth->login(URL::full()); } }
return $next($request);
}
Since Laravel 5.3, you can change your unauthenticated method.
For example, it can be:
**App/Exceptions/Handler.php**
```php
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson())
{
return response()->json(['error' => 'Unauthenticated.'], 401); // Or, return a response that causes client side js to redirect to '/routesPrefix/myIdp1/login'
}
$saml2Auth = new Saml2Auth(Saml2Auth::loadOneLoginAuthFromIpdConfig('mytestidp1'));
return $saml2Auth->login('/my/redirect/path');
}
…
'saml2_controller' => 'App\Http\Controllers\MyNamespace\MySaml2Controller'
App/Http/Controllers/MyNamespace/MySaml2Controller.php
use Aacotroneo\Saml2\Http\Controllers\Saml2Controller;
class MySaml2Controller extends Saml2Controller
{
public function login()
{
$loginRedirect = '...'; // Determine redirect URL
$this->saml2Auth->login($loginRedirect);
}
}
After login is called, the user will be redirected to the IDP login page. Then the IDP, which you have configured with an endpoint the library serves, will call back, e.g. /mytestidp1/acs or /{routesPrefix}/mytestidp1/acs. That will process the response and fire an event when ready. The next step for you is to handle that event. You just need to login the user or refuse.
For example, it can be:
App/Providers/MyEventServiceProvider.php
Event::listen('Aacotroneo\Saml2\Events\Saml2LoginEvent', function (Saml2LoginEvent $event) {
$messageId = $event->getSaml2Auth()->getLastMessageId();
// Add your own code preventing reuse of a $messageId to stop replay attacks
$user = $event->getSaml2User();
$userData = [
'id' => $user->getUserId(),
'attributes' => $user->getAttributes(),
'assertion' => $user->getRawSamlAssertion()
];
$laravelUser = //find user by ID or attribute
//if it does not exist create it and go on or show an error message
Auth::login($laravelUser);
});
Be careful about necessary Laravel middleware for Auth persistence in Session.
For example, it can be:
App/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
...
],
'api' => [
...
],
'saml' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
],
config/saml2_settings.php
/**
* which middleware group to use for the saml routes
* Laravel 5.2 will need a group which includes StartSession
*/
'routesMiddleware' => ['saml'],
…
php
Event::listen('Aacotroneo\Saml2\Events\Saml2LogoutEvent', function ($event) {
Auth::logout();
Session::save();
});
That's it. Feel free to ask any questions, make PR or suggestions, or open Issues.
暂无开放 Issues,或尚未同步最近议题。