Installation:
composer require adactive-sas/saml2-bridge-bundle
Ensure your composer.json includes "adactive-sas/saml2-bridge-bundle": "^x.y.z" (replace with latest version).
Bundle Registration:
Add to config/bundles.php (Symfony 4.3+):
return [
// ...
AdactiveSas\Saml2BridgeBundle\AdactiveSasSaml2BridgeBundle::class => ['all' => true],
];
Configuration: Publish the default config:
php bin/console config:dump-reference AdactiveSasSaml2BridgeBundle
Override in config/packages/adactive_sas_saml2_bridge.yaml:
adactive_sas_saml2_bridge:
idp:
entity_id: "https://yourdomain.com/saml/idp/metadata"
name: "Your Identity Provider"
x509cert: "%kernel.project_dir%/config/saml/cert.pem"
private_key: "%kernel.project_dir%/config/saml/key.pem"
authn:
binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Metadata Generation: Generate and expose metadata endpoint:
php bin/console adactive:saml:metadata:generate
Access metadata at /saml/idp/metadata.
First Use Case: Configure a Service Provider (SP) in your SAML IdP dashboard (e.g., Azure AD, Okta) with:
https://yourdomain.com/saml/sp/metadata (SP metadata URL)https://yourdomain.com/saml/acs (Assertion Consumer Service)Initiate SSO: Redirect users to SP’s SAML endpoint with:
use AdactiveSas\Saml2BridgeBundle\Service\SamlService;
$samlService = $this->container->get(SamlService::class);
$samlService->initiateSso($spEntityId, $returnUrl);
This generates a signed AuthnRequest and redirects to the SP.
Handle Assertion Consumer Service (ACS):
Override the default ACS controller or use the bundle’s built-in route (/saml/acs):
// src/Controller/SamlController.php
use AdactiveSas\Saml2BridgeBundle\Controller\SamlController;
class CustomSamlController extends SamlController
{
public function acsAction(Request $request)
{
$response = parent::acsAction($request);
// Custom logic (e.g., user mapping, role assignment)
return $response;
}
}
Register the route in config/routes.yaml:
saml_acs:
path: /saml/acs
controller: App\Controller\CustomSamlController::acsAction
Map SAML attributes to Laravel users:
# config/packages/adactive_sas_saml2_bridge.yaml
adactive_sas_saml2_bridge:
idp:
attributes:
username: "urn:oid:0.9.2342.19200300.100.1.1" # SAML attribute for email
first_name: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
last_name: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
Use the SamlUserProvider to fetch or create users:
$userProvider = $this->container->get('adactive_sas_saml2_bridge.user_provider');
$user = $userProvider->loadUserByUsername($samlAttributes['username']);
Trigger logout from your application:
$samlService->initiateLogout($spEntityId, $returnUrl);
Or handle SP-initiated logout at /saml/slo.
Service Container Binding:
Bind the bundle’s services to Laravel’s container in AppServiceProvider:
public function register()
{
$this->app->bind(
AdactiveSas\Saml2BridgeBundle\Service\SamlService::class,
function ($app) {
return new SamlService(
$app['adactive_sas_saml2_bridge.saml'],
$app['adactive_sas_saml2_bridge.user_provider']
);
}
);
}
Middleware for Protected Routes: Create middleware to verify SAML sessions:
// app/Http/Middleware/VerifySamlSession.php
public function handle($request, Closure $next)
{
if (!$request->hasSession() || !$request->session()->has('saml_authenticated')) {
return redirect()->route('saml.login');
}
return $next($request);
}
Apply to routes:
# config/routes.yaml
_saml_protected:
path: /protected
middleware: ['web', 'saml.session']
Event Listeners:
Listen to SAML events (e.g., SamlAuthenticateEvent) for custom logic:
// app/Listeners/SamlAuthListener.php
public function handle(SamlAuthenticateEvent $event)
{
$user = $event->getUser();
// Assign roles, log activity, etc.
}
Register in EventServiceProvider:
protected $listen = [
'AdactiveSas\Saml2BridgeBundle\Event\SamlAuthenticateEvent' => [
'App\Listeners\SamlAuthListener',
],
];
Certificate Management:
openssl rsa -in key.pem -out key_no_pass.pem
openssl x509 -in cert.pem -noout -dates
Metadata Mismatches:
entity_id in both SP and IdP configurations. Use absolute URLs.Debugging SAML Errors:
config/packages/monolog.yaml:
handlers:
saml:
type: stream
path: "%kernel.logs_dir%/saml.log"
level: debug
channels: ["saml"]
Invalid signature: Certificate or key misconfiguration.Message expired: Clock skew or NotOnOrAfter validation.Attribute Mapping:
urn:oid:... for OIDs).Session Handling:
$request->getSession()->invalidate();
Testing:
docker run --rm -p 8080:80 -v $(pwd)/saml:/var/www/simplesaml simplesamlphp/simplesamlphp:latest
config/simplesamlphp/metadata/saml20-sp-hosted.php.Performance:
# config/packages/adactive_sas_saml2_bridge.yaml
adactive_sas_saml2_bridge:
cache_metadata: true
metadata_cache_lifetime: 3600 # 1 hour
Security:
debug: false in production config.$this->app->middleware(EnsureHttps::class);
Customization:
How can I help you explore Laravel packages today?