Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Samlidp Laravel Package

codegreencreative/laravel-samlidp

A Laravel package that turns your app into a SAML Identity Provider (IdP), with SSO endpoints, service provider management, metadata, and certificate handling so Laravel can authenticate users for external SAML service providers.

View on GitHub
Deep Wiki
Context7

Getting Started

v5.4.0 is a compatibility-only release: it adds Laravel 13.x support with no new features, config keys, or API changes. Treat it as a green light to run the package on Laravel 13, not as an upgrade that requires code changes.

  1. Install and pin. composer require codegreencreative/laravel-samlidp. On Laravel 13 you need ^5.4; on Laravel 12 or older, ^5.3 remains fine. If Composer refuses to resolve, run composer why-not codegreencreative/laravel-samlidp 5.4.0 and check the PHP floor (Laravel 13 raises it) plus the robrichards/xmlseclibs / SAML toolkit transitive constraints. The service provider is auto-discovered.
  2. Publish the config. php artisan vendor:publish --provider="CodeGreenCreative\SamlIdp\SamlIdpServiceProvider" gives you config/samlidp.php — this is the first file to read, since it holds the base URL, cert/key paths, SP definitions, and signing/encryption settings.
  3. Generate an IdP keypair. Use the package's certificate command (check php artisan list for the exact samlidp:* signature in your version) or generate manually with openssl req -x509 -newkey rsa:2048 -nodes. Store both files outside the web root (e.g. storage/app/samlidp/), chmod 600 the key, and point cert_path / key_path at absolute paths.
  4. Set the canonical base URL. SAML_IDP_BASE_URL must be the exact HTTPS origin the SPs will call. Everything in the metadata (entity ID, SSO/SLO endpoints, ACS URLs) is derived from it.
  5. Register the listeners. SSO/SLO are handed back to your app for actual authentication; wire CodeGreenCreative\SamlIdp\Events\SamlLogin and SamlLogout in EventServiceProvider (or Event::listen in a service provider).
  6. Hand out metadata. Give the SP https://your-app.test/saml/metadata. First use case: point a free SP sandbox or a local test SP at that URL, hit /saml/login from the SP, and confirm you land back at the SP's ACS with a valid Assertion and the attributes you expect.

Implementation Patterns

SP-initiated SSO (the default flow). The SP redirects the browser to your SSO endpoint with an AuthnRequest. The package parses and validates it, then hands control to you. Your SamlLogin listener should resolve/authenticate the user (session, remember-me, SSO against an upstream IdP) and make sure Auth::user() is populated before the response is built — the assertion attributes are read from the authenticated user afterwards. Keep the listener thin: delegate to an action class so it is unit-testable without HTTP.

Attribute mapping as a first-class concern. Don't scatter getAttribute() calls through listeners. Put the claim set (email, uid, displayName, roles, groups) in one place — a config array or a small SamlAttributes class — keyed off the user model. This is the single highest-leverage abstraction in the package: every SP wants different NameID and attribute names, and every new SP becomes a config diff instead of a code change.

Multiple SPs / multi-tenancy. The config supports a map of service providers keyed by entity ID. Resolve the SP from the Issuer on the incoming request rather than from a session or URL segment, otherwise a user with two SP tabs open gets the wrong assertion. For per-tenant branding or ACS URLs, layer a tenant-resolving middleware in front of the package routes.

IdP-initiated SSO. For "click the tile in our dashboard" launches, build a link to your login endpoint with the target SP plus a RelayState carrying the deep link. Note this path has no AuthnRequest to validate, so you own replay protection and the "which SP?" decision.

Single logout. Handle SamlLogout by invalidating the local session and flushing any app-level SSO state, then let the package return the LogoutResponse. Test both SP-initiated and IdP-initiated logout; they fail in different ways (stale session vs. broken redirect chain).

Testing. Write feature tests against the endpoints: build a signed AuthnRequest fixture (or grab one from a real SP's debug output), post it to the SSO endpoint, base64-decode the returned SAMLResponse, and assert on the assertion XML with DOMDocument + XPath. Assert the signature verifies rather than string-matching XML. For the attribute builder, plain unit tests are enough.

Deployment. php artisan config:cache and route:cache must be run after any env change; SAML failures after a deploy are frequently just a cached config with an old base URL. For certificate rotation, plan a dual-publish window — most SPs will not accept a silent key swap, so coordinate a metadata re-import before retiring the old cert.

Gotchas and Tips

  • Proxies and URL generation. Behind a load balancer, base_url and the generated endpoints can drift to http:// or an internal host, producing metadata that SPs reject on signature/recipient mismatch. Fix with TrustProxies plus an explicit SAML_IDP_BASE_URL; never rely on APP_URL alone.
  • Cert format. The private key must be an unencrypted PEM; a passphrase-protected key yields an opaque signing failure. Absolute paths only — relative paths resolve against the entry point, which differs between php artisan serve, Octane, and queue workers.
  • Clock skew. Validity windows in the assertion are short. If the IdP and SP hosts disagree even slightly, SPs reject with NotBefore/NotOnOrAfter errors that look like signing errors. Keep hosts on NTP.
  • Silent listener. If SSO redirects to the SP but the assertion is empty or the user is anonymous, the listener is almost certainly not registered — check EventServiceProvider::$listen and run php artisan event:clear after editing.
  • NameID stability. Changing the user identifier (email → UUID) breaks every SP that stores the NameID as a persistent key. Decide the format early and treat it as a public contract.
  • Metadata caching on the SP side. Your config changes look like "the package is broken" when the SP is simply serving cached metadata. Always re-import after cert, endpoint, or attribute changes.
  • No local state. The package is stateless — no tables, no session store of its own. Any "who is logged in where" tracking for SLO is yours to build.
  • Debugging. Enable the toolkit's debug output in config/samlidp.php in non-production, tail storage/logs/laravel.log, and validate responses with the SAML-tracer browser extension or xmlsec1 --verify before blaming the package. Most "bad signature" reports are malformed base64 (a + turned into a space by sloppy form encoding).
  • Extension points. Prefer the event listeners and published config over editing vendor code; if you need to change route behaviour, define your own routes ahead of the package's and add the package's middleware group rather than disabling the provider. Any custom implementation can be swapped in via container binding if you outgrow the defaults.
  • Laravel 13 upgrade. Because v5.4.0 is compat-only, the risk surface is your dependency graph, not the SAML logic. Run the full SSO/SLO flow against a staging SP on Laravel 13 before promoting, and keep a ^5.3 branch deployable until that passes.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log