- Introduced `ddev` configuration for Laravel-based SAML SSO setup. - Added detailed technical specifications for SAML 2.0 integration, including endpoints, flows, and cryptographic signing. - Created extensive unit tests to validate `SamlIdpController` and `SamlIdpService` functionalities. - Enhanced metadata generation, SAML request parsing, and cryptographic signing of responses. - Implemented models, services, and tests to standardize IdP interactions with Service Providers.
103 lines
7.9 KiB
Markdown
103 lines
7.9 KiB
Markdown
# SAML 2.0 SSO Integration Diagram & Specifications
|
|
|
|
This document provides a comprehensive technical reference for the SAML 2.0 Identity Provider (IdP) integration. It
|
|
includes sequence diagrams, an endpoint directory, and data flow models detailing request/response payloads, service
|
|
responsibilities, and cryptographic boundaries.
|
|
|
|
---
|
|
|
|
## End-to-End SSO Authentication Flow
|
|
|
|
Below is the complete sequence diagram detailing how a user authenticates into **Microsoft Teams / Outlook** via this
|
|
Laravel SSO Identity Provider.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
actor User as User Browser
|
|
participant MS as Microsoft Entra ID<br/>(Service Provider)
|
|
participant IdP as Laravel SSO Portal<br/>(Identity Provider)
|
|
participant DB as Database
|
|
%% Step 1-3: SP Redirection
|
|
User ->> MS: 1. Access Microsoft Teams/Outlook (e.g. user@company.com)
|
|
MS ->> MS: 2. Detect company.com is federated to Laravel SSO Portal
|
|
MS ->> User: 3. Redirect with SAMLRequest & RelayState (HTTP-Redirect)
|
|
%% Step 4: Access SSO Endpoint
|
|
User ->> IdP: 4. Request /saml/sso?SAMLRequest=...&RelayState=...
|
|
%% Step 5-6: Auth Check & Interception
|
|
alt User is NOT Authenticated
|
|
IdP ->> IdP: 5a. Save SAMLRequest & RelayState to Session
|
|
IdP ->> User: 5b. Redirect to /login
|
|
User ->> IdP: 5c. User inputs credentials (Fortify login)
|
|
IdP ->> DB: 5d. Authenticate user
|
|
IdP ->> User: 5e. Redirect to /dashboard (ResolveDashboardRouteController)
|
|
Note over IdP, User: ResolveDashboardRouteController intercepts session,<br/>detects saml_pending_request, redirects back to /saml/sso
|
|
User ->> IdP: 5f. Request /saml/sso (Authenticated)
|
|
else User IS Authenticated
|
|
Note over User, IdP: Immediately proceed to Step 6
|
|
end
|
|
|
|
%% Step 7: Parse and Retrieve
|
|
IdP ->> DB: 6. Match SAML Issuer (SP Entity ID) against ConnectedApps
|
|
DB -->> IdP: Return Connected App metadata & SAML configurations
|
|
%% Step 8-11: Response Generation
|
|
Note over IdP: App\Services\SamlIdpService<br/>1. Build SAML Response XML<br/>2. Retrieve User email & immutable_id<br/>3. Cryptographically sign Assertion node using idp.key
|
|
IdP ->> IdP: 7. Base64 encode signed SAML XML
|
|
IdP ->> IdP: 8. Clear SAML pending request from session
|
|
IdP -->> User: 9. Render post_response.blade.php with hidden auto-submitting form
|
|
%% Step 12-14: Microsoft ACS Callback
|
|
User ->> MS: 10. POST SAMLResponse & RelayState to Microsoft ACS URL
|
|
Note over MS: 1. Validate XML Signature against IdP public certificate (idp.crt)<br/>2. Map SAML NameID claim to user's ImmutableId
|
|
MS -->> User: 11. Grant secure access to Microsoft Teams & Outlook!
|
|
```
|
|
|
|
---
|
|
|
|
## SAML 2.0 Endpoint Directory
|
|
|
|
This table maps all endpoints involved in the SAML 2.0 integration, including input values, controller and service
|
|
responsibilities, and outputs.
|
|
|
|
| Endpoint | HTTP Method | Request Inputs / Parameters | Internal Service Called | Core Responsibility | Response Output |
|
|
|:---------------------|:---------------|:-------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------|
|
|
| **`/saml/metadata`** | `GET` | *None* | `App\Services\SamlIdpService@generateMetadata` | Generates the IdP's official SAML 2.0 XML metadata descriptor to share signing certificates and SSO endpoints with external systems. | `200 OK` (XML payload)<br/>`Content-Type: application/xml` |
|
|
| **`/saml/sso`** | `GET` / `POST` | `SAMLRequest` (base64/deflated)<br/>`RelayState` (optional redirect URL) | `App\Services\SamlIdpService@parseRequest`<br/>`App\Services\SamlIdpService@findConnectedApp`<br/>`App\Services\SamlIdpService@generateResponse` | - Decodes and parses SAMLRequest.<br/>- Matches Issuer (Entity ID) to an active SAML Connected App.<br/>- Redirects guests to `/login` with session preservation.<br/>- Intercepts authenticated sessions to build and sign SAML XML assertions. | `200 OK` (renders redirect view) or `302 Redirect` to `/login` |
|
|
| **`/dashboard`** | `GET` | *Session Cookie* | `App\Helpers\DashboardRoute` | Intercepts successful post-login routing. If the session holds a pending SAML request, redirects the browser back to `/saml/sso`. | `302 Redirect` to `/saml/sso` (if pending) or dashboard routes |
|
|
|
|
---
|
|
|
|
## Data Mapping & Cryptographic Flow
|
|
|
|
Here is the step-by-step overview of how the Laravel Identity Provider translates local user attributes into a
|
|
cryptographically signed assertion accepted by Microsoft:
|
|
|
|
```
|
|
[Local Database] [Cryptographic Signing]
|
|
User: Private Key: storage/app/saml/idp.key
|
|
├── email: user@company.com Public Cert: storage/app/saml/idp.crt
|
|
└── immutable_id: user-123-immutable │
|
|
│ ▼
|
|
│ (Maps to) ┌───────────────────────────┐
|
|
▼ │ XMLSecLibs RSA-SHA256 │
|
|
┌─────────────────────────────┐ │ Signs <saml:Assertion> │
|
|
│ SAML Assertion Claims │────────>│ Moves <Signature> node │
|
|
│ - NameID: persistent │ │ before <Subject> for │
|
|
│ - IDPEmail: user@company │ │ schema validation. │
|
|
│ - mail: user@company │ └───────────────────────────┘
|
|
│ - upn: user@company │ │
|
|
└─────────────────────────────┘ ▼
|
|
┌───────────────────────────┐
|
|
│ Base64-encoded Payload │
|
|
│ SAMLResponse = PHNhb... │
|
|
└───────────────────────────┘
|
|
```
|
|
|
|
### Claim & Attribute Mapping Details
|
|
|
|
Microsoft Entra ID maps the incoming assertion elements exactly to the cloud user directory:
|
|
|
|
- **`saml:NameID` (persistent format)**: Directly maps to the user's **`ImmutableId`** (configured locally in the admin
|
|
panel or auto-generated deterministically as the base64-encoded user ID).
|
|
- **`IDPEmail` / `upn` claims**: Map to the user's **`UserPrincipalName`** (the email address used for login inside
|
|
Microsoft 365, e.g. `user@company.com`).
|