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-xmldependency. This module hand-rolls a small, purpose-built XML parser ([xml], private) instead — see that module’s docs for why.sso-samladds no new dependency beyond whatssoalready 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. OnlyRSA-SHA256is 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 (gzipoutput 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, unsignedAuthnRequestXML to the IdP.AuthnRequests are never signed —sign_requests/sp_private_keyfrom the design sketch don’t exist. This crate has no private-key PEM/DER parser (the same reasonsuper::server’sAuthServersigns its own tokens HS256 instead of RSA/EC), and most IdPs (Okta, Azure AD, Google Workspace, Keycloak) accept unsignedAuthnRequests by default — the flow’s security rests on the IdP-signed Assertion, which this module does verify.- Logout is local-only.
/saml/logoutdestroys the SP’s own session and redirects home; there is no SP-initiatedLogoutRequest/LogoutResponseexchange with the IdP (true SAML Single Logout). This mirrorssuper::OidcAuth’s own logout, which draws the identical boundary for OIDC’send_session_endpoint. AttributeMapmaps into a plainname_id/attributesstruct (SamlClaims), notsuper::OidcClaims. The design sketch’s own example maps agroupsattribute, butOidcClaims(Phase 2) was deliberately built without agroupsfield — 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§
- Attribute
Map - Maps IdP-specific SAML attribute names to caller-chosen field names.
- Saml
Claims - The verified identity from a completed SAML login, injected as the
CLAIMS_HEADERrequest header (JSON). - Saml
Config - Configuration for
SamlSp. - Saml
IdpMetadata - Parsed IdP SAML metadata — everything the SP needs to build an
AuthnRequestand verify a signedResponse. - 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.