PHPackages                             maize-tech/laravel-saml2-sp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. maize-tech/laravel-saml2-sp

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

maize-tech/laravel-saml2-sp
===========================

Laravel Saml2 Service Provider

1.0.0(today)00[1 PRs](https://github.com/maize-tech/laravel-saml2-sp/pulls)MITPHPPHP ^8.2CI passing

Since Jun 26Pushed today4 watchersCompare

[ Source](https://github.com/maize-tech/laravel-saml2-sp)[ Packagist](https://packagist.org/packages/maize-tech/laravel-saml2-sp)[ Docs](https://github.com/maize-tech/laravel-saml2-sp)[ RSS](/packages/maize-tech-laravel-saml2-sp/feed)WikiDiscussions main Synced today

READMEChangelog (2)Dependencies (18)Versions (2)Used By (0)

Laravel SAML2 Service Provider
==============================

[](#laravel-saml2-service-provider)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1eb8668a04deffb1d7716acad69c3c5f2fc9f21ef929804b16612c1d6b6d16fd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d61697a652d746563682f6c61726176656c2d73616d6c322d73702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/maize-tech/laravel-saml2-sp)[![GitHub Tests Action Status](https://camo.githubusercontent.com/38ba8a7003b1619d06f93d9b8c3264f6419378fe5e6fe05cb912d846608c83ab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d61697a652d746563682f6c61726176656c2d73616d6c322d73702f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473)](https://github.com/maize-tech/laravel-saml2-sp/actions/workflows/run-tests.yml)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/744065e57a43d834a5f39429e022dd23c431fd8be89993e7aa4e957b5642ddf2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d61697a652d746563682f6c61726176656c2d73616d6c322d73702f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65)](https://github.com/maize-tech/laravel-saml2-sp/actions/workflows/fix-php-code-style-issues.yml)[![Total Downloads](https://camo.githubusercontent.com/956f772f975c1f06a103836d60d52c8ccb0477bb32eeecca2657ed413b72902f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d61697a652d746563682f6c61726176656c2d73616d6c322d73702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/maize-tech/laravel-saml2-sp)

This package lets you add SAML2 authentication support within your application.

It acts as a SAML2 **Service Provider** (SP): it exposes the SP metadata, redirects users to your Identity Provider (IdP) for authentication, consumes the IdP assertion to log the user in, and handles single logout. Under the hood it wraps [onelogin/php-saml](https://github.com/SAML-Toolkits/php-saml) and stores one or more SAML configurations in the database.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require maize-tech/laravel-saml2-sp
```

You can publish the config and migration files and run the migrations with:

```
php artisan saml2-sp:install
```

This is the content of the published config file:

```
return [

    /*
    |--------------------------------------------------------------------------
    | User model
    |--------------------------------------------------------------------------
    |
    | Here you may specify the fully qualified class name of the user model.
    |
    */

    'user_model' => null,

    /*
    |--------------------------------------------------------------------------
    | Authentication guard
    |--------------------------------------------------------------------------
    |
    | Here you may specify the guard you want to use to authenticate the user.
    | The guard name must be defined in your application's auth.php config file.
    | When null, the default guard specified in 'auth.php' will be used.
    |
    */

    'auth_guard' => null,

    /*
    |--------------------------------------------------------------------------
    | Config model
    |--------------------------------------------------------------------------
    |
    | Here you may specify the fully qualified class name of the config model.
    |
    */

    'config_model' => Maize\Saml2Sp\Models\SamlConfig::class,

    /*
    |--------------------------------------------------------------------------
    | Config finder
    |--------------------------------------------------------------------------
    |
    | Here you may specify the fully qualified class name of the config finder class.
    |
    */

    'config_finder' => Maize\Saml2Sp\DefaultSamlConfigFinder::class,

    /*
    |--------------------------------------------------------------------------
    | Enable proxy vars
    |--------------------------------------------------------------------------
    |
    | Here you may specify whether you want to enable proxy vars or not.
    | When true, the package will trust proxy headers such as
    | HTTP_X_FORWARDED_PROTO.
    | Useful when your application is running behind a load balancer.
    |
    */

    'proxy_vars_enabled' => false,

    /*
    |--------------------------------------------------------------------------
    | Login return url
    |--------------------------------------------------------------------------
    |
    | Here you may specify the url where users should be redirected after login.
    | Used as default variable if no return url is specified in the login request.
    |
    */

    'login_return_url' => null,

    /*
    |--------------------------------------------------------------------------
    | Logout return url
    |--------------------------------------------------------------------------
    |
    | Here you may specify the url where users should be redirected after logout.
    | Used as default variable if no return url is specified in the logout request.
    |
    */

    'logout_return_url' => null,

    /*
    |--------------------------------------------------------------------------
    | Domain whitelist
    |--------------------------------------------------------------------------
    |
    | Here you may specify the list of whitelisted domains accepted as return url.
    | The package will only check for the first and second level domain excluding
    | the url schema and path.
    |
    */

    'domain_whitelist' => [
        //
    ],

    /*
    |--------------------------------------------------------------------------
    | Route configurations
    |--------------------------------------------------------------------------
    |
    | Here you may specify whether routes should be enabled or not.
    | You can also customize the routes prefix and middlewares.
    |
    */

    'routes' => [
        'enabled' => true,
        'prefix' => 'saml2',
        'middleware' => ['web'],
    ],

    'actions' => [

        /*
        |--------------------------------------------------------------------------
        | Authenticate user
        |--------------------------------------------------------------------------
        |
        | Here you may specify the fully qualified class name of the auth action.
        | If needed, you may define your own action, which should override the
        | default one.
        |
        */

        'authenticate_user' => Maize\Saml2Sp\Actions\AuthenticateUser::class,

        /*
        |--------------------------------------------------------------------------
        | Logout user
        |--------------------------------------------------------------------------
        |
        | Here you may specify the fully qualified class name of the logout action.
        | If needed, you may define your own action, which should override the
        | default one.
        |
        */

        'logout_user' => Maize\Saml2Sp\Actions\LogoutUser::class,

    ],

    'default_values' => [

        /*
        |--------------------------------------------------------------------------
        | Strict mode
        |--------------------------------------------------------------------------
        |
        | Here you may specify whether the communication between the service and
        | identity providers should be validated or not.
        | When true, all requests with invalid data will be automatically rejected.
        |
        */

        'strict' => true,

        /*
        |--------------------------------------------------------------------------
        | Debug mode
        |--------------------------------------------------------------------------
        |
        | Here you may specify whether the debug mode is enabled or not.
        | When true, most authentication errors will be printed out.
        |
        */

        'debug' => false,

        /*
        |--------------------------------------------------------------------------
        | Organization values
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default organization values in many languages.
        | When needed, you may include another translation following the ISO 639-1
        | standard language codes.
        |
        */

        'organization' => [
            'en-US' => [
                'url' => null,
                'name' => null,
                'displayname' => null,
            ],
        ],

        /*
        |--------------------------------------------------------------------------
        | Contact information values
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default technical and support values.
        |
        */

        'contactPerson' => [
            'support' => [
                'givenName' => null,
                'emailAddress' => null,
            ],
            'technical' => [
                'givenName' => null,
                'emailAddress' => null,
            ],
        ],

        /*
        |--------------------------------------------------------------------------
        | Service provider values
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default saml service provider values.
        |
        */

        'sp' => [
            'entityId' => null,
            'x509cert' => null,
            'privateKey' => null,
            'singleLogoutService' => [
                'url' => null,
            ],
            'assertionConsumerService' => [
                'url' => null,
            ],
        ],

        /*
        |--------------------------------------------------------------------------
        | Identity provider values
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default saml identity provider values.
        |
        */

        'idp' => [
            'entityId' => null,
            'x509cert' => null,
            'singleLogoutService' => [
                'url' => null,
            ],
            'singleSignOnService' => [
                'url' => null,
            ],
        ],

        /*
        |--------------------------------------------------------------------------
        | Security values
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default saml security values.
        |
        */

        'security' => [
            //
        ],

    ],

];
```

Usage
-----

[](#usage)

### Minimum configuration

[](#minimum-configuration)

After publishing the config file, set at least the following keys in `config/saml2-sp.php` (or via your environment):

- `user_model`: the fully qualified class name of your authenticatable user model.
- `login_return_url`: where users are redirected after a successful login.
- `logout_return_url`: where users are redirected after logout.
- `domain_whitelist`: the list of domains accepted as return urls. Any `return_url` / `RelayState` whose host is not whitelisted falls back to the configured return url. This prevents open-redirect attacks.

```
'user_model' => App\Models\User::class,

'login_return_url' => 'https://my-app.test/dashboard',

'logout_return_url' => 'https://my-app.test/login',

'domain_whitelist' => [
    'my-app.test',
],
```

Both `login_return_url` and `logout_return_url` also accept a closure or the class name of an invokable class, so you can resolve the destination at runtime:

```
'login_return_url' => fn () => route('dashboard'),
```

### Creating a SAML configuration

[](#creating-a-saml-configuration)

SAML settings are stored in the database through the `SamlConfig` model. Each row holds the service provider (`sp`) and identity provider (`idp`) sections, merged at runtime with the `default_values` defined in the config file. The `sp`, `idp`, `security`, `contactPerson` and `organization` columns are transparently encrypted.

```
use Maize\Saml2Sp\Models\SamlConfig;

SamlConfig::create([
    'strict' => true,
    'debug' => false,
    'sp' => [
        'entityId' => 'https://my-app.test/saml2/metadata',
        'assertionConsumerService' => [
            'url' => 'https://my-app.test/saml2/acs',
        ],
        'singleLogoutService' => [
            'url' => 'https://my-app.test/saml2/sls',
        ],
        'x509cert' => '...your SP certificate...',
        'privateKey' => '...your SP private key...',
    ],
    'idp' => [
        'entityId' => 'https://idp.example.com/metadata',
        'singleSignOnService' => [
            'url' => 'https://idp.example.com/sso',
        ],
        'singleLogoutService' => [
            'url' => 'https://idp.example.com/slo',
        ],
        'x509cert' => '...your IdP certificate...',
    ],
]);
```

### Routes

[](#routes)

When `routes.enabled` is `true` (the default), the package registers the following routes under the configured prefix (`saml2` by default) and middleware (`web`):

MethodURINameDescription`GET``saml2/metadata``saml2.metadata`Returns the SP metadata XML to share with your IdP.`GET``saml2/login``saml2.login`Builds the authentication request and redirects to the IdP.`POST``saml2/acs``saml2.acs`Assertion Consumer Service: consumes the IdP response and logs in.`GET``saml2/logout``saml2.logout`Builds the logout request and redirects to the IdP.`GET/POST``saml2/sls``saml2.sls`Single Logout Service: logs the user out and redirects back.A typical flow looks like this:

1. Share `saml2/metadata` with your Identity Provider.
2. Send the user to `saml2/login` (optionally with a whitelisted `?return_url=`). They are redirected to the IdP to authenticate.
3. The IdP posts the assertion back to `saml2/acs`. The package validates it, resolves the matching user and logs them in, then redirects to the `RelayState` (if whitelisted) or to `login_return_url`.
4. To log out, send the user to `saml2/logout`. After the IdP processes it, the `saml2/sls` endpoint logs the user out locally and redirects to `logout_return_url`.

You may disable the built-in routes (`routes.enabled => false`) and register your own pointing to the package controllers if you need full control.

### Events

[](#events)

The package dispatches two events you can listen to:

- `Maize\Saml2Sp\Events\SamlLoggedIn` — after a user is authenticated through the ACS endpoint.
- `Maize\Saml2Sp\Events\SamlLoggedOut` — after a user is logged out through the SLS endpoint.

Both expose the affected user via a public `$user` property:

```
use Maize\Saml2Sp\Events\SamlLoggedIn;

class NotifyUserLoggedIn
{
    public function handle(SamlLoggedIn $event): void
    {
        logger()->info('SAML login', ['id' => $event->user->getAuthIdentifier()]);
    }
}
```

### Customizing the authentication logic

[](#customizing-the-authentication-logic)

The default `AuthenticateUser` action looks up the user by matching its `email`column against the SAML `nameId`, then logs it in through the configured guard. The default `LogoutUser` action logs out the currently authenticated user.

You can replace either action with your own by pointing the config to a custom class:

```
'actions' => [
    'authenticate_user' => App\Saml\AuthenticateUser::class,
    'logout_user' => App\Saml\LogoutUser::class,
],
```

A custom authenticate action receives the `Maize\Saml2Sp\SamlUserData` instance (name id, attributes and friendly-name attributes) and must return an `Illuminate\Contracts\Auth\Authenticatable`:

```
use Illuminate\Contracts\Auth\Authenticatable;
use Maize\Saml2Sp\SamlUserData;

class AuthenticateUser
{
    public function __invoke(SamlUserData $userData): Authenticatable
    {
        $user = User::firstOrCreate(
            ['email' => $userData->nameId],
            ['name' => $userData->getAttribute('displayName', onlyFirst: true)],
        );

        auth()->login($user);

        return $user;
    }
}
```

### Resolving the configuration per request (multi-tenant)

[](#resolving-the-configuration-per-request-multi-tenant)

By default the `DefaultSamlConfigFinder` returns the first `SamlConfig` row. If you serve several Identity Providers (e.g. one per tenant or domain), implement your own finder and register it in the config:

```
use Illuminate\Http\Request;
use Maize\Saml2Sp\Models\SamlConfig;
use Maize\Saml2Sp\SamlConfigFinder;

class TenantSamlConfigFinder extends SamlConfigFinder
{
    public static function findForRequest(Request $request): ?SamlConfig
    {
        return SamlConfig::query()
            ->where('tenant_id', $request->user()?->tenant_id)
            ->first();
    }
}
```

```
'config_finder' => App\Saml\TenantSamlConfigFinder::class,
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/maize-tech/.github/blob/main/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](https://github.com/maize-tech/.github/security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Enrico De Lazzari](https://github.com/enricodelazzari)
- [Riccardo Dalla Via](https://github.com/riccardodallavia)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/848d3feb1799fbdb3ff475a4398017f9bc2b94c5cba4dd69d414af62a856fcc4?d=identicon)[maize-tech](/maintainers/maize-tech)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (7 commits)")[![enricodelazzari](https://avatars.githubusercontent.com/u/10452445?v=4)](https://github.com/enricodelazzari "enricodelazzari (7 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")[![riccardodallavia](https://avatars.githubusercontent.com/u/1372062?v=4)](https://github.com/riccardodallavia "riccardodallavia (4 commits)")

---

Tags

laravelSAML2serviceprovidermaize-tech

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/maize-tech-laravel-saml2-sp/health.svg)

```
[![Health](https://phpackages.com/badges/maize-tech-laravel-saml2-sp/health.svg)](https://phpackages.com/packages/maize-tech-laravel-saml2-sp)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76518.2M120](/packages/laravel-mcp)[spatie/laravel-health

Monitor the health of a Laravel application

87411.3M153](/packages/spatie-laravel-health)[laravel/cashier-paddle

Cashier Paddle provides an expressive, fluent interface to Paddle's subscription billing services.

267880.7k3](/packages/laravel-cashier-paddle)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)[simplestats-io/laravel-client

Analytics for Laravel. Track visitors, registrations, and payments. Discover which channels actually drive revenue, not just traffic. Server-side, GDPR compliant, ad-blocker proof.

5019.3k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
