{"id":15293920,"url":"https://github.com/rootinc/laravel-saml2-middleware","last_synced_at":"2025-08-07T18:48:12.790Z","repository":{"id":51048605,"uuid":"279942872","full_name":"rootinc/laravel-saml2-middleware","owner":"rootinc","description":null,"archived":false,"fork":false,"pushed_at":"2021-05-25T14:52:33.000Z","size":41,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-24T01:20:25.979Z","etag":null,"topics":["laravel","laravel-framework","php","saml2"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rootinc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-15T18:11:03.000Z","updated_at":"2023-07-21T09:56:31.000Z","dependencies_parsed_at":"2022-09-03T23:23:23.950Z","dependency_job_id":null,"html_url":"https://github.com/rootinc/laravel-saml2-middleware","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rootinc%2Flaravel-saml2-middleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rootinc%2Flaravel-saml2-middleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rootinc%2Flaravel-saml2-middleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rootinc%2Flaravel-saml2-middleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rootinc","download_url":"https://codeload.github.com/rootinc/laravel-saml2-middleware/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248721091,"owners_count":21151045,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","laravel-framework","php","saml2"],"created_at":"2024-09-30T16:53:41.374Z","updated_at":"2025-04-13T13:31:29.386Z","avatar_url":"https://github.com/rootinc.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Saml2 Middleware\n\nProvides Saml2 Authentication Middleware for a Laravel App.  If you like this, checkout \u003ca href=\"https://github.com/rootinc/laravel-azure-middleware\"\u003eLaravel Azure Middleware\u003c/a\u003e\n\n## Normal Installation\n\n1. `composer require rootinc/laravel-saml2-middleware`\n2. run `php artisan vendor:publish --provider=\"RootInc\\LaravelSaml2Middleware\\Saml2ServiceProvider\"` to install config file to `config/saml2.php`\n3. In our routes folder (most likely `web.php`), add\n```php\nRoute::get('/login/saml2', '\\RootInc\\LaravelSaml2Middleware\\Saml2@saml2');\nRoute::post('/login/saml2callback', '\\RootInc\\LaravelSaml2Middleware\\Saml2@saml2callback');\n```\n\n4. In our `App\\Http\\Kernel.php` add `'saml2' =\u003e \\RootInc\\LaravelSaml2Middleware\\Saml2::class,` most likely to the `$routeMiddleware` array.\n5. In our `.env` optionally add `SAML2_STRICT, SAML2_SAML2_PROXY_VARS`.  If not added, these values will default to true.\n6. In our `.env` add `SAML2_IDP_ENTITYID, SAML2_IDP_SSO, SAML2_IDP_SLO and SAML2_IDP_x509`.\n7. In our `.env` optionally add `SAML2_SP_NAME_ID_FORMAT, SAML2_SP_ENTITY_ID, SAML2_SP_SSO, SAML2_SP_SLO, SAML2_SP_x509, SAML2_SP_PRIVATE_KEY`.  These values are only required to override if the default config does not suffice.\n8. In our `App\\Http\\Middleware\\VerifyCsrfToken.php` add `'/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` to the `$except` array.\n9. Add the `saml2` middleware to your route groups on any routes that needs protected by auth and enjoy :tada:\n10. If you need custom callbacks, see [Extended Installation](#extended-installation).\n\n## Routing\n\n`Route::get('/login/saml2', '\\RootInc\\LaravelSaml2Middleware\\Saml2@saml2');` First parameter can be wherever you want to route the saml2 login.  * Change as you would like.\n\n`Route::post('/login/saml2callback', '\\RootInc\\LaravelSaml2Middleware\\Saml2@saml2callback');` First parameter can be whatever you want to route after your callback.  * Change as you would like.\n\n`Route::get('/logout/saml2', '\\RootInc\\LaravelSaml2Middleware\\Saml2@saml2logout');` First parameter can be whatever you want to route after your callback.  * Change as you would like.\n\n`Route::post('/logout/logoutcallback', '\\RootInc\\LaravelSaml2Middleware\\Saml2@logoutcallback');` First parameter can be whatever you want to route after your callback.  * Change as you would like.\n\n* Note - if we change these values, it is important to see [Service Provider Options Override](#service-provider-options-override)\n\n## Metadata\n\nAs of of v0.2.0, we added the ability to get the metadata.  Simply add:\n\n`Route::get('/saml2/metadata', '\\RootInc\\LaravelSaml2Middleware\\Saml2@saml2metadata');` First parameter can be whatever you want to route for the metadata.  * Change as you would like.\n\n* Note - if we change these values, it is important to see [Service Provider Options Override](#service-provider-options-override)\n\n## Extended Installation\n\nThe out-of-the-box implementation let's you login users.  However, let's say we would like to store this user into a database, as well as login the user in with Laravel Auth.  There are two callbacks that are recommended to extend from the Saml2 class called `success` and `fail`. The following provides information on how to extend the Root Laravel Saml2 Middleware Library:\n\n1. To get started (assuming we've followed the [Normal Installation](#normal-installation) directions), create a file called `AppSaml2.php` in the `App\\Http\\Middleware` folder.  You can either do this through `artisan` or manually.\n2. Add this as a starting point in this file:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse RootInc\\LaravelSaml2Middleware\\Saml2 as Saml2;\n\nuse Auth;\n\nuse App\\User;\n\nclass AppSaml2 extends Saml2\n{\n    protected function success($request, $token, $profile)\n    {\n        $email = mb_strtolower($profile['Email'][0]);\n\n        $user = User::updateOrCreate(['email' =\u003e $email], [\n            'firstName' =\u003e $profile['FirstName'][0],\n            'lastName' =\u003e $profile['LastName'][0],\n        ]);\n\n        Auth::login($user, true);\n\n        return parent::success($request, $token, $profile);\n    }\n}\n```\n\nThe above gives us a way to add/update users after a successful handshake.  `$profile` contains all sorts of metadata that we use to create or update our user.  The default implementation redirects to the intended url, or `/`, so we call the parent here.  Feel free to not extend the default and to redirect elsewhere.\n\n3. Our routes need to be updated to the following:\n\n```php\nRoute::get('/login/saml2', '\\App\\Http\\Middleware\\AppSaml2@saml2');\nRoute::post('/login/saml2callback', '\\App\\Http\\Middleware\\AppSaml2@saml2callback');\nRoute::get('/logout/saml2', '\\App\\Http\\Middleware\\AppSaml2@saml2logout');\nRoute::post('/logout/logoutcallback', '\\App\\Http\\Middleware\\AppSaml2@logoutcallback');\n```\n\nAs of v0.2.0, if using the metadata route, we'll want to update to be:\n`Route::get('/saml2/metadata', '\\App\\Http\\Middleware\\AppSaml2@saml2metadata');`\n\n4. Finally, update `Kernel.php`'s `saml2` key to be `'saml2' =\u003e \\App\\Http\\Middleware\\AppSaml2::class,`\n\n## Service Provider Options Override\n\nAs of v0.2.0, we added options for overriding the default behavior for the service provider.  The defaults should generally work well for our app.  However, configuration is always beneficial.  Here are those keys and their default values:\n\n* `SAML2_SP_NAME_ID_FORMAT` defaults to `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`\n* `SAML2_SP_ENTITY_ID` defaults to `url(\"/saml2/metadata\")`\n* `SAML2_SP_SSO` defaults to `url(\"/login/saml2callback\")`\n* `SAML2_SP_SLO` defaults to `url(\"/logout/saml2callback\")`\n* `SAML2_SP_x509` defaults to `\"\"`\n* `SAML2_SP_PRIVATE_KEY` defaults to `\"\"`\n\nIt's important that if we are not following the naming conventions of the readme, that we update `SAML2_SP_ENTITY_ID, SAML2_SP_SSO, SAML2_SP_SLO` values.\n\n## Other Extending Options\n\n#### Callback on Every Handshake\n\nA callback after every successful request (handshake) is available for Saml2.  The default is to simply call the `$next` closure.  However, let's say we want to update the user.  Here's an example of how to go about that:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse Closure;\n\nuse RootInc\\LaravelSaml2Middleware\\Saml2 as Saml2;\n\nuse Auth;\nuse Carbon\\Carbon;\n\nuse App\\User;\n\nclass AppSaml2 extends Saml2\n{\n    protected function handlecallback($request, Closure $next, $token)\n    {\n        $user = Auth::user();\n\n        $user-\u003eupdated_at = Carbon::now();\n\n        $user-\u003esave();\n\n        return parent::handlecallback($request, $next, $token);\n    }\n}\n```\n\nBuilding off of our previous example from [Extended Installation](#extended-installation), we have a user in the Auth now (since we did `Auth::login` in the success callback).  With the user model, we can update the user's `updated_at` field.  The callback should call the closure, `$next($request);` and return it.  In our case, the default implementation does this, so we call the parent here.\n\n#### Custom Redirect\n\nThe ability to customize the redirect method is available for Saml2.  For example, if the session token's expire, but the user is still authenticated with Laravel, we can check for that with this example:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse RootInc\\LaravelSaml2Middleware\\Saml2 as Saml2;\n\nuse Auth;\n\nclass AppSaml2 extends Saml2\n{\n    protected function redirect($request)\n    {\n        if (Auth::user() !== null)\n        {\n            return $this-\u003esaml2($request);\n        }\n        else\n        {\n            return parent::redirect($request);\n        }\n    }\n}\n```\n\n#### Different Login Route\n\nThe ability to change the `$login_route` in the middleware is available for Saml2.  Building off [Extended Installation](#extended-installation), in our `AppSaml2` class, we can simply set `$login_route` to whatever.  For example:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse RootInc\\LaravelSaml2Middleware\\Saml2 as Saml2;\n\nclass AppSaml2 extends Saml2\n{\n    protected $login_route = \"/\";\n}\n```\n\nThe above would now set `$login_route` to `/` or root.\n\n#### Getting / Overriding the Saml2 Route\n\nThe ability to get the Saml2 URL is available for Saml2.  For example, let's say we wanted to modify the Saml2 URL so that it also passed the user's email to Saml2 as a parmater.  Building off [Extended Installation](#extended-installation), in our `AppSaml2` class, we could do something like this:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse RootInc\\LaravelSaml2Middleware\\Saml2 as Saml2;\n\nuse Auth;\n\nclass AppSaml2 extends Saml2\n{\n    //we could overload this if we wanted too.\n    public function getSaml2Url($email = null)\n    {\n        return $this-\u003egetAuth()-\u003elogin(null, [], false, false, true, true, $email);\n    }\n\n    public function saml2(Request $request)\n    {\n        $user = Auth::user();\n\n        $away = $this-\u003egetSaml2Url($user ? $user-\u003eemail : null);\n\n        return redirect()-\u003eaway($away);\n    }\n}\n```\n\n## Testing with Laravel Saml2 Middleware\n\nWe can integrate with Laravel's tests by calling `actingAs` for HTTP tests or `loginAs` with Dusk.  This assumes that we are using the `Auth::login` method in the success callback, shown at [Extended Installation](#extended-installation).  There is no need to do anything in our `AppSaml2` class, unless we needed to overwrite the default behavior, which is shown below:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse RootInc\\LaravelSaml2Middleware\\Saml2 as Saml2;\n\nuse Auth;\n\nclass AppSaml2 extends Saml2\n{\n    //this is the default behavior\n    //overwrite to meet your needs\n    protected function handleTesting(Request $request, Closure $next)\n    {\n        $user = Auth::user();\n\n        if (!isset($user))\n        {\n            return $this-\u003eredirect($request, $next);\n        }\n\n        return $this-\u003ehandlecallback($request, $next, null);\n    }\n}\n```\n\nThe above will call the class's redirect method, if it can't find a user in Laravel's auth.  Otherwise, the above will call the class's handlecallback method.  Therefore, tests can check if the correct redirection is happening, or that handlecallback is working correctly (which by default calls `$next($request);`).\n\n## Contributing\n\nThank you for considering contributing to the Laravel Saml2 Middleware! To encourage active collaboration, we encourage pull requests, not just issues.\n\nIf you file an issue, the issue should contain a title and a clear description of the issue. You should also include as much relevant information as possible and a code sample that demonstrates the issue. The goal of a issue is to make it easy for yourself - and others - to replicate the bug and develop a fix.\n\n## License\n\nThe Laravel Saml2 Middleware is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frootinc%2Flaravel-saml2-middleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frootinc%2Flaravel-saml2-middleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frootinc%2Flaravel-saml2-middleware/lists"}