italia / spid-laravel
Laravel Package for SPID authentication
Requires
- php: ^8.2|^8.3
- cweagans/composer-patches: ^1.7
- illuminate/config: ^9.52.4|^10.0|^11.0|^12.0
- illuminate/support: ^9.52.4|^10.0|^11.0|^12.0
- nesbot/carbon: ^2.66|^3.0
- onelogin/php-saml: 4.1.0
- robrichards/xmlseclibs: ^3.1.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ~3.51.0
- mikey179/vfsstream: ^1.6
- mockery/mockery: ^1.5.1
- orchestra/testbench: ^7.22.1|^8.0|^9.0|^10.0
- pds/skeleton: ~1.0
- phpunit/phpunit: ^9.5.10|^10.0|^11.0
- symfony/http-foundation: ^6.4.29|^7.3.7
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v2.1.0-beta
- v2.0.4-beta
- v2.0.3-beta
- v2.0.2-beta
- v2.0.1-beta
- v2.0.0-beta
- v1.4.1-beta
- v1.4.0-beta
- v1.3.0-beta
- v1.2.7-beta
- v1.2.6-beta
- v1.2.5-beta
- v1.2.4-beta
- v1.2.3-beta
- v1.2.2-beta
- v1.2.0-beta
- v1.1.0-beta
- v1.0.1-beta
- v1.0.0-beta
- v0.16.0-beta
- v0.15.0-beta
- v0.14.0-beta
- v0.13.0-beta
- v0.12.0-beta
- v0.11.0-beta
- v0.10.0-beta
- v0.9.7-beta
- v0.9.6-beta
- v0.9.5-beta
- v0.9.4-beta
- v0.9.3-beta
- v0.9.2-beta
- v0.9.1-beta
- v0.9.0-beta
- v0.8.0-beta
- v0.7.0-beta
- v0.6.0-beta
- v0.5.0-beta
- v0.4.0-beta
- v0.3.0-beta
- v0.2.0-beta
- v0.1.0-beta
- dev-transactions
This package is auto-updated.
Last update: 2026-10-12 14:48:56 UTC
README
SPID authentication package for Laravel
This is a package to provide a simple SPID authentication system to web applications based on Laravel.
See Changelog for more informations about versions and breaking changes.
Requirements
| Laravel | PHP |
|---|---|
| 9.x | 8.2 |
| 10.x | 8.2, 8.3 |
| 11.x | 8.2 – 8.4 |
| 12.x | 8.2 – 8.5 |
| 13.x | 8.3 – 8.5 |
The package depends on onelogin/php-saml
^4.3.1 and robrichards/xmlseclibs
^3.1.5.
Installation
-
Before installing this package patching must be enabled in
composer.json. This is necessary because this patch has to be applied to onelogin/php-saml for SPID compatibility.Edit your
composer.jsonlike this:... "extra": { "enable-patching": "true" }, ...
or simply run:
composer config extra.enable-patching true.Since this package is still in beta,
minimum-stabilityoption must be set tobetaand theprefer-stableoption must be set totrueincomposer.json.These options can be set by running:
composer config minimum-stability beta composer config prefer-stable true
For Windows only
Composer needs the patch command to be installed (it is not part of Windows). To enable it install Git then add the C:\Program Files\Git\usr\bin folder to the system path.
This installation step will be removed before the first stable release of this package.
-
Require this package with composer.
composer require italia/spid-laravel -
Exclude the URIs used by this package from CSRF protection because the the Identity Providers can't know what CSRF token include in their POST requests sent to your routes.
In your
app/Http/Middleware/VerifyCsrfToken.phpset'/spid/*'as an element of the$exceptarray.<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware { /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = [ '/spid/*' ]; }
Configuration
Publish the configuration with:
php artisan vendor:publish --provider="Italia\SPIDAuth\ServiceProvider"
This will create a spid-auth.php file in your config directory where you can
set these options:
Service Provider options
sp_entity_id: Service Provider Entity ID;sp_organization_name: Service Provider Organization Name;sp_organization_display_name: Service Provider Organization Display Name;sp_organization_url: Service Provider Organization URL;sp_requested_attributes: SPID attributes requested to Identity Providers.
These options must be set accordingly to the official SPID technical rules.
The values entered in the config file will be used to generate the SAML Service
Provider metadata at runtime. The generated metadata will be available in XML
format at /spid/metadata.
Testing (multi-version)
This repository includes tools and CI configuration to run the full test suite against multiple Laravel and PHP versions.
The script test-laravel-versions.sh replicates the CircleCI matrix locally
using Docker: every supported PHP/Laravel combination (see
Requirements) runs in a cimg/php:<version> container. Each
job installs the dependencies for the Laravel major (applying the SPID patch to
php-saml), checks the IdP certificates, validates the package structure, runs
php-cs-fixer and composer audit, and finally runs PHPUnit with the matching
phpunit-*.xml config.
Docker must be installed and running. The original composer.json and
composer.lock are backed up and restored when the script exits.
Quick examples
Run the full matrix:
./test-laravel-versions.sh
Run tests for Laravel 12 on every supported PHP version:
./test-laravel-versions.sh 12
Run tests for Laravel 12 on PHP 8.3 only:
./test-laravel-versions.sh 12 8.3
SPID IdP certificates
The certificates in config/spid-idps.php can be checked against the official
SPID registry with:
composer spid:idps:check # exits non-zero on mismatches composer spid:idps:update # rewrites the x509cert values in config/spid-idps.php
Bindings
Due to limitations of onelogin/php-saml,
only the HTTP-POST binding is supported for the AssertionConsumerService
endpoint and the HTTP-Redirect for the the SingleLogoutService endpoint.
Application options
middleware_group: the middleware group assigned to the packages routes. The default value iswebwhich comes with Laravel out of the box and provides some common features like session management and cookies. You can add more middlewares using an array butwebmust be always included.routes_prefix: the route prefix applied to the package routes. If you change the defaultspidvalue make sure to reflect this change in theapp/Http/Middleware/VerifyCsrfToken.phpfile as described above. Please note that in this document the value is assumed to bespid.login_view: the view to display when the user is redirected by the packagespid.authmiddleware (see Middleware section below). The default view isspid-auth::login-spid.after_login_url: the URL to redirect to after a successful login. If the login process is triggered by the packagespid.authmiddleware, the user will be redirected to the original destination. Default value is/.after_logout_url: the URL to redirect to after a successful logout. Default value is/.
Please note that the php artisan vendor:publish --provider="Italia\SPIDAuth\ServiceProvider"
command will copy some static assets to your public directory. You can publish
configuration and assets separately adding --tag=spid-config and
--tag=spid-assets options on the command line.
Cookies
Due to the specific working mode of the SameSite cookie parameter, this package
can only work with lax or none policy. Thus the config option
session.same_site MUST be set accordingly.
Usage
The SPID authentication process is completely agnostic about the authentication
system of your application. If you plan to integrate your authentication system
with SPID, you can listen to the LoginEvent and LogoutEvent (see
Events and Example).
SPIDAuth Service Provider
If you need more customization in the authentication logic of your application,
you can use the methods available in the SPIDAuth Service Provider.
First you need an instance of the Service Provider from the Service Container:
$SPIDAuth = app('SPIDAuth');
The following public methods can be used in your application.
| Method | Description |
|---|---|
| login | Show the configured login_view with a SPID button, if authenticated redirect to after_login_url. |
| doLogin | Attempt login with the SPID Identity Provider in the current request and redirect to the intended or configured after_login_url if authenticated. |
| acs | Process the POST response from Identity Providers, set session variables and redirect to the intended or configured after_login_url. |
| logout | Attempt logout with the SPID Identity Provider stored in the current session. |
| isAuthenticated | Check if the current session is authenticated with SPID. |
| metadata | Show metadata for this SPID Service Provider. |
| providers | Identity Providers list in JSON format used by the SPID smart button. |
| getSPIDUser | Return the current authenticated SPIDUser or null if not authenticated. |
Button
You can display a simple SPID access button by including the
spid-auth::spid-button view in your template:
@include('spid-auth::spid-button')
Optionally you can specify the button size (s, m, l or xl):
@include('spid-auth::spid-button', ['size' => 'm'])
To display the button dropdown right aligned you can set the rightAlign
parameter to true.
@include('spid-auth::spid-button', ['rightAlign' => true])
Your templates must include a @stack('styles') directive inside the head
tag and a @stack('scripts') directive inside the body tag (after the
SPID access button markup code).
The button is the official spid-sp-access-button and requires jQuery.
Scenario
- The user clicks on the button and a list of Identity Provider is displayed;
- The user choose an Identity Provider and is redirected to the corresponding login page;
- After a successful login the user is redirected to the URL specified in the
after_login_urloption and aLoginEventis triggered.
Middleware
You can assign the spid.auth middleware to specific routes like so:
Route::get('private', 'PrivateController@show')->middleware('spid.auth');
Or you can assign the spid.auth middleware to application controllers:
class PrivateController extends Controller { /** * Instantiate a new controller instance. * * @return void */ public function __construct() { $this->middleware('spid.auth'); } }
Scenario
- The user requests a resource which
spid.authmiddleware is assigned to. - The user is redirected to
/spid/loginand the view specified inlogin_viewoption is displayed; - The user choose an Identity Provider and is redirected to the corresponding login page;
- After a successful login the user is redirected to the URL of the original
resource and a
LoginEventis triggered.
Events
LoginEvent and LogoutEvent can be listened to get some useful information
about the authenticated user. Both events share these methods:
getSPIDUser()returns aSPIDUserobject filled with the attributes specified in thesp_requested_attributesoption and returned by the Identity Provider;getIdp()returns the entityName of the Identity Provider.
To listen to both events using the same object, you can use an Event Subscriber class that can be defined as follow:
<?php namespace App\Listeners; use Italia\SPIDAuth\Events\LoginEvent; use Italia\SPIDAuth\Events\LogoutEvent; class SPIDEventSubscriber { /** * Handle SPID login events. */ public function onSPIDLogin($event) { // $event->getSPIDUser() and $event->getIdp() are available here // your application logic goes here } /** * Handle SPID logout events. */ public function onSPIDLogout($event) { // $event->getSPIDUser() and $event->getIdp() are available here // your application logic goes here } /** * Register the listeners for the subscriber. * * @param Illuminate\Events\Dispatcher $events */ public function subscribe($events) { $events->listen( LoginEvent::class, [ SPIDEventSubscriber::class, 'onSPIDLogin' ] ); $events->listen( LogoutEvent::class, [ SPIDEventSubscriber::class, 'onSPIDLogout' ] ); } }
The SPIDEventSubscriber class must be added to the $subscribe array in
app/Providers/EventServiceProvider.php:
protected $subscribe = [ SPIDEventSubscriber::class, ];
The SPIDUser class provides <attribute> properties for the attributes
specified in the sp_requested_attributes option (e.g. for the name attribute
you find a SPIDUser->name property). If the attribute is not available null
is returned.
Logout
Simply provide your users a link pointing to /spid/logout.
Scenario
- The user clicks on a link pointing to
/spid/logout; - After a successful logout the user is redirected to the URL specified in the
after_logout_urloption and aLogoutEventis triggered.
Example
This package comes with a simple set of controllers, views and routes that can be run as an example in a fresh installed Laravel application.
To publish the needed files run the command:
php artisan spid-auth:example
This will create the following files:
app/Http/Controllers/HomeController.phpapp/Http/Controllers/PrivateController.phpapp/Listeners/SPIDEventSubscriber.phpresources/views/layouts/app.blade.phpresources/views/home.blade.phpresources/views/private.blade.php
Next add the SPIDEventSubscriber class in
app/Providers/EventServiceProvider.php as described above.
You can open storage/logs/laravel.log to read some example informations logged by the
SPIDEventSubscriber.
Notes
Security
Make sure to set your timezone in app/config/app.php because the id of every
assertion consumed is cached to prevent replay attacks. This feature rely on a
correct timezone configuration of your app.
HTTPS
As required in the SPID technical specifications, the Service Provider MUST accept messages in HTTPS only.
According to this requirement, some cookies in this package are created with
Secure policy, thus the authentication does not work in an unsecure context.
Test Identity Provider
In the
spid-idps.php
file are defined the official
SPID Identity Providers.
For testing purposes, this file includes also a test Identity Provider. Refer to the SPID Test Environment to get more informations about SPID authentication testing.
The test Identity Provider can be enabled/disabled using the test_idp entry
in your config/spid-auth.php file.
'test_idp' => [ 'entityId' => '<Test IdP entityId>', 'sso_endpoint' => '<Test IdP SingleSignOnService endpoint>', 'slo_endpoint' => '<Test IdP SingleLogoutService endpoint>', 'x509cert' => '<Test IdP x509 certificate>', ],
Set 'test_idp' => false to disable.
Testing with SPID Validator and SPID Demo
Before submitting the Service Provider metadata to AgID, the SPID technical procedure asks to verify the Service Provider with two AgID tools from spid-saml-check:
- SPID Validator: checks the metadata, the AuthnRequest and the Response handling.
- SPID Demo: a test Identity Provider with demo users.
Prerequisites
- The application must be reachable over HTTPS on a public hostname (a tunnel is fine for development).
expose_sp_metadatamust betrue; the metadata URL ishttps://<host>/<routes_prefix>/metadata(/spid/metadataby default).- The SPID patch for
onelogin/php-samlmust be applied: the output ofcomposer installmust not containCould not apply patch!.
Configuration
Configure validator_idp with the values of
https://validator.spid.gov.it/metadata.xml and test_idp with the values of
https://demo.spid.gov.it/metadata.xml. The test Identity Provider entry
is reused for SPID Demo.
| Config key | Metadata value |
|---|---|
entityId |
EntityDescriptor/@entityID |
sso_endpoint |
SingleSignOnService[@Binding="...HTTP-Redirect"]/@Location |
slo_endpoint |
SingleLogoutService[@Binding="...HTTP-Redirect"]/@Location |
x509cert |
KeyDescriptor[@use="signing"]//X509Certificate (body only, no PEM headers) |
'validator_idp' => [ 'entityId' => 'https://validator.spid.gov.it', 'sso_endpoint' => 'https://validator.spid.gov.it/samlsso', 'slo_endpoint' => 'https://validator.spid.gov.it/samlsso', 'x509cert' => '<signing certificate from https://validator.spid.gov.it/metadata.xml>', ], 'test_idp' => [ 'entityId' => 'https://demo.spid.gov.it', 'sso_endpoint' => 'https://demo.spid.gov.it/samlsso', 'slo_endpoint' => 'https://demo.spid.gov.it/samlsso', 'x509cert' => '<signing certificate from https://demo.spid.gov.it/metadata.xml>', ],
The SSO endpoint is .../samlsso; https://demo.spid.gov.it/start, shown
in the browser during a login, is an internal step of SPID Demo and must not
be used as sso_endpoint. The certificates are rotated: always copy them
from the metadata URLs above.
Running the checks
- Log in to https://validator.spid.gov.it (user
validator, passwordvalidator), open Metadata / Download from URL, enter your metadata URL, then run Metadata / Check Strict and Metadata / Check Extra. - Start a login from your application choosing the SPID Validator button: the validator shows the result in Request / Check Strict and Request / Check Extra.
- Start a login choosing the Test IdP button to authenticate on SPID Demo with one of the demo users.
Troubleshooting SPID Demo errors
| Message | Cause |
|---|---|
Formato richiesta non corretto. Verificare che il metadata sia stato registrato. |
The SP metadata is not registered on SPID Validator, or the Issuer of the request (your sp_entity_id) differs from the registered entityID. Register it again after changing the certificate, sp_entity_id, sp_base_url, sp_acs_index, sp_attributes_index or the requested attributes. |
Formato richiesta non corretto. La AuthnRequest non supera i controlli strict. |
The AuthnRequest fails a strict check: metadata not registered again after a change (see above), SPID patch not applied, sso_endpoint not ending in /samlsso, application served over HTTP instead of HTTPS, or server clock skew (IssueInstant). |
Formato richiesta non corretto. La AuthnRequest non supera i controlli extra. |
The AuthnRequest passes the strict checks but fails the extra ones. |
Formato richiesta non corretto. AuthnContextClassRef non corretto. |
sp_spid_level is not one of https://www.spid.gov.it/SpidL1, SpidL2, SpidL3. |
The per-check report is on SPID Validator, Request / Check Strict (and
Check Extra). The same checks can be run locally with
spid-sp-test, saving the full
redirect URL of the login (the Location header of POST /spid/login) to a
file:
IDP_ENTITYID=https://demo.spid.gov.it spid_sp_test \
--metadata-url https://<host>/spid/metadata \
--authn-url file://authn-request.dump \
--profile spid-sp-private --extra
Use --profile spid-sp-public for a public administration.
Service Provider certificate and private key
In the
spid-auth.php
file are defined the X.509 certificate and the private key of the Service
Provider. Please note that the values provided are only for testing purposes and
can't be used in production.
You can set your own X.509 certificate and private key in the
config/spid-auth.php file of your application (which overrides the one in the
package).
The X.509 certificate and the private key can be configured as strings or as
paths to files. If both are specified in your config/spid-auth.php then the
ones specified as strings will take precedence.
Change the values and keep the private key secret.
Licenses
BSD-3-Clause License is generally applied to all the code in this repository if not otherwise specified.
MIT License is applied to some portions of code as reported in
this README.
SIL Open Font License 1.1 is applied to the Titillium font included from CSS files.