Skip to main content

Module saml

Module saml 

Source
Available on crate features sso-saml and sso only.
Expand description

SamlSp — a SAML 2.0 Service Provider middleware.

Enterprise / B2B SSO (AD FS, Okta SAML, Google Workspace SAML), as an alternative to the OIDC-based super::OidcAuth for IdPs that only speak SAML.

§Usage

use std::sync::Arc;
use rust_web_server::app::App;
use rust_web_server::core::New;
use rust_web_server::session::SessionStore;
use rust_web_server::sso::saml::{SamlSp, SamlConfig, SamlIdpMetadata, AttributeMap};

let saml_sp = SamlSp::new(SamlConfig {
    sp_entity_id: "https://myapp.com/saml/metadata".into(),
    sp_acs_url:   "https://myapp.com/saml/acs".into(),
    idp_metadata: SamlIdpMetadata::from_file("idp-metadata.xml").unwrap(),
    sessions:     Arc::new(SessionStore::new(86_400)),
})
.attribute_map(
    AttributeMap::new()
        .map("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "email")
        .map("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "name"),
);

let app = App::new().wrap(saml_sp);
// Registers: GET /saml/metadata, GET /saml/login, POST /saml/acs, GET /saml/logout

§Deviations from the original design sketch

  • No quick-xml dependency. This module hand-rolls a small, purpose-built XML parser ([xml], private) instead — see that module’s docs for why. sso-saml adds no new dependency beyond what sso already pulls in.
  • Signature verification is byte-exact, not full XML C14N — see [assertion]’s (private) module docs for the detailed rationale and its fail-closed-not-fail-open safety argument. Only RSA-SHA256 is supported.
  • AuthnRequests use the HTTP-POST binding, not HTTP-Redirect. HTTP-Redirect requires DEFLATE-compressing the request, and this crate has no compression dependency to reuse (gzip output elsewhere in this crate is hand-rolled for responses, not a general-purpose DEFLATE encoder suitable for reuse here). HTTP-POST is an equally spec-compliant binding — an auto-submitting HTML form POSTs the base64-encoded, unsigned AuthnRequest XML to the IdP.
  • AuthnRequests are never signed — sign_requests/ sp_private_key from the design sketch don’t exist. This crate has no private-key PEM/DER parser (the same reason super::server’s AuthServer signs its own tokens HS256 instead of RSA/EC), and most IdPs (Okta, Azure AD, Google Workspace, Keycloak) accept unsigned AuthnRequests by default — the flow’s security rests on the IdP-signed Assertion, which this module does verify.
  • Logout is local-only. /saml/logout destroys the SP’s own session and redirects home; there is no SP-initiated LogoutRequest/LogoutResponse exchange with the IdP (true SAML Single Logout). This mirrors super::OidcAuth’s own logout, which draws the identical boundary for OIDC’s end_session_endpoint.
  • AttributeMap maps into a plain name_id/attributes struct (SamlClaims), not super::OidcClaims. The design sketch’s own example maps a groups attribute, but OidcClaims (Phase 2) was deliberately built without a groups field — reusing it here would silently drop exactly the attribute the sketch’s own example asks to map. SAML’s free-form attribute model is a better fit for a plain map than OIDC’s fixed claim set.

Structs§

AttributeMap
Maps IdP-specific SAML attribute names to caller-chosen field names.
SamlClaims
The verified identity from a completed SAML login, injected as the CLAIMS_HEADER request header (JSON).
SamlConfig
Configuration for SamlSp.
SamlIdpMetadata
Parsed IdP SAML metadata — everything the SP needs to build an AuthnRequest and verify a signed Response.
SamlSp
A SAML 2.0 Service Provider — see the module docs.

Constants§

CLAIMS_HEADER
Request header name used to pass SAML claims into downstream handlers.