Weave Code
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

Lightsaml Laravel Package

aerialship/lightsaml

SAML 2.0 toolkit for Laravel/PHP to add SSO and identity federation to your apps. Provides helpers for SAML authentication flows, metadata, and certificate handling, making it easier to integrate with common IdPs and SPs.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require aerialship/lightsaml
    
    • Verify lightsaml is autoloaded in composer.json.
  2. First Use Case: Basic SAML Auth Flow

    • Initialize the library in a service provider (e.g., AuthServiceProvider):
      use Lightsaml\AuthnRequest;
      use Lightsaml\Binding\RedirectBinding;
      
      $acsUrl = url('/saml/acs'); // Assertion Consumer Service URL
      $issuer = 'https://your-app.example.com';
      
      $authnRequest = new AuthnRequest($acsUrl, $issuer);
      $binding = new RedirectBinding();
      $request = $binding->buildAuthnRequest($authnRequest);
      
    • Redirect the user to the IdP (Identity Provider) with the generated request:
      return redirect($request->getLocation());
      
  3. Where to Look First

    • Documentation: Check the GitHub repo (if available) or inline PHPDoc comments in src/Lightsaml/.
    • Core Classes:
      • AuthnRequest (for SP-initiated login).
      • Response (for parsing IdP responses).
      • Bindings (RedirectBinding, PostBinding) for request/response formats.
    • Examples: Look for tests/ or examples/ directories in the package (if present).

Implementation Patterns

Common Workflows

  1. SP-Initiated Login (Redirect Binding)

    • Generate an AuthnRequest with ACS URL and issuer.
    • Use RedirectBinding to serialize and redirect to IdP.
    • Handle IdP response via ACS endpoint:
      $response = new Response($_POST); // For POST binding
      $binding = new PostBinding();
      $binding->validateResponse($response);
      
  2. IdP-Initiated Login (Handle Incoming Responses)

    • Validate the SAML response in your ACS endpoint:
      $response = new Response($_GET); // For redirect binding
      $binding = new RedirectBinding();
      if ($binding->validateResponse($response)) {
          $attributes = $response->getAttributes();
          // Map attributes to Laravel user (e.g., via `auth()->loginUsingId($userId)`).
      }
      
  3. Logout Requests

    • Generate a logout request:
      $logoutRequest = new LogoutRequest($acsUrl, $issuer);
      $binding = new RedirectBinding();
      $request = $binding->buildLogoutRequest($logoutRequest);
      
    • Redirect to IdP logout endpoint, then handle IdP-initiated logout via a logout ACS endpoint.
  4. Metadata Handling

    • Parse IdP metadata (XML) to extract endpoints/keys:
      use Lightsaml\Metadata\IdpMetadata;
      $metadata = new IdpMetadata(file_get_contents('idp-metadata.xml'));
      $acsUrl = $metadata->getSingleSignOnService('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect');
      

Integration Tips

  • Laravel-Specific:

    • Store SAML state (e.g., RelayState) in the session:
      session(['saml_relay_state' => $relayState]);
      
    • Use middleware to validate responses or enforce HTTPS:
      Route::middleware(['saml.secure'])->post('/saml/acs', 'SAMLController@handleResponse');
      
    • Extend Laravel’s User model to hydrate from SAML attributes:
      public static function findForSAML(array $attributes) {
          return self::where('email', $attributes['email'][0])->first();
      }
      
  • Error Handling:

    • Wrap SAML operations in try-catch blocks to handle validation errors:
      try {
          $binding->validateResponse($response);
      } catch (ValidationError $e) {
          Log::error("SAML Validation Failed: " . $e->getMessage());
          return redirect('/login')->withErrors(['saml' => 'Invalid response']);
      }
      
  • Testing:

    • Mock IdP responses in unit tests using Lightsaml\Response:
      $response = new Response([
          'SAMLResponse' => base64_encode($validSamlXml),
          'RelayState' => '/dashboard'
      ]);
      

Gotchas and Tips

Pitfalls

  1. Binding Mismatches

    • Ensure the binding used to send the request (RedirectBinding/PostBinding) matches the binding expected by the IdP/SP.
    • Example: If the IdP expects HTTP-POST, use PostBinding for the AuthnRequest.
  2. Clock Skew

    • SAML responses must be validated within a time window (default: 5 minutes). Configure the library to handle this:
      $response->setAllowedClockSkew(300); // 5 minutes in seconds
      
  3. Signature Validation

    • Always validate signatures unless the IdP is trusted implicitly. Disable only in development:
      $response->setSignatureValidation(false); // Not recommended for production!
      
  4. Character Encoding

    • SAML responses may be URL-encoded or base64-encoded. Decode them before parsing:
      $samlResponse = base64_decode($_POST['SAMLResponse']);
      
  5. Metadata Expiry

    • IdP metadata (e.g., certificates) can expire. Cache metadata but implement a fallback to re-fetch if validation fails.
  6. Laravel Session Conflicts

    • If using PostBinding, ensure the session is not corrupted by the POST request. Clear or rehydrate the session after handling the response.

Debugging Tips

  • Enable Verbose Logging Add this to your config/logging.php to capture SAML XML:

    'channels' => [
        'saml' => [
            'driver' => 'single',
            'path' => storage_path('logs/saml.log'),
            'level' => 'debug',
        ],
    ],
    

    Log raw SAML requests/responses:

    Log::channel('saml')->debug('SAML Response', ['raw' => $response->getXml()]);
    
  • Validate XML Manually Use an online SAML validator (e.g., SAML Tracer) to debug malformed requests/responses.

  • Check Certificate Trust If signature validation fails, verify the IdP’s certificate is trusted:

    $cert = $response->getSigningCertificate();
    openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER);
    

Extension Points

  1. Custom Attribute Mapping Override Lightsaml\Response to map IdP attributes to Laravel users:

    $user = User::updateOrCreate(
        ['email' => $response->getAttribute('email')[0]],
        [
            'name' => $response->getAttribute('givenName')[0] ?? '',
            'saml_uid' => $response->getAttribute('uid')[0]
        ]
    );
    
  2. Dynamic ACS URLs Generate ACS URLs dynamically based on user roles:

    $acsUrl = route('saml.acs', ['role' => 'admin']);
    
  3. IdP Discovery Implement a dropdown to let users select their IdP, then dynamically generate AuthnRequests:

    $idpMetadata = new IdpMetadata($selectedIdpMetadataXml);
    $acsUrl = $idpMetadata->getAssertionConsumerService();
    
  4. Caching Cache SAML responses or metadata to reduce processing overhead:

    Cache::remember('idp_metadata', 3600, function () {
        return new IdpMetadata(file_get_contents('idp-metadata.xml'));
    });
    
  5. Event Listeners Dispatch Laravel events for SAML flows (e.g., SAMLLoginAttempting, SAMLLoginFailed):

    event(new SAMLLoginAttempting($response));
    
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.
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui