Skip to main content

rustauth_saml/
options.rs

1use std::collections::BTreeMap;
2
3use rustauth_core::secret::SecretString;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8/// SAML configuration for an enterprise SSO provider.
9pub struct SamlProviderConfig {
10    /// Service provider issuer/entity id expected by the IdP.
11    pub issuer: String,
12    #[serde(default)]
13    /// IdP SSO entry point for AuthnRequest redirects.
14    pub entry_point: String,
15    /// IdP signing certificate, either PEM or base64 body.
16    pub cert: String,
17    /// RustAuth callback URL used after SAML login.
18    pub callback_url: String,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    /// Explicit assertion consumer service URL.
21    pub acs_url: Option<String>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    /// Expected SAML audience. Defaults to issuer semantics when omitted.
24    pub audience: Option<String>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    /// Parsed or configured IdP metadata.
27    pub idp_metadata: Option<SamlIdpMetadata>,
28    /// Service provider metadata configuration.
29    pub sp_metadata: SamlSpMetadata,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    /// Provider attribute mapping.
32    pub mapping: Option<SamlMapping>,
33    /// Require valid XMLDSig over the SAML Assertion.
34    #[serde(default = "default_want_assertions_signed")]
35    pub want_assertions_signed: bool,
36    /// Sign outbound AuthnRequest messages.
37    pub authn_requests_signed: bool,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    /// Signature algorithm URI or short name for outbound signed requests.
40    pub signature_algorithm: Option<String>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    /// Digest algorithm URI or short name for outbound signed requests.
43    pub digest_algorithm: Option<String>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    /// SAML NameID format requested from the IdP.
46    pub identifier_format: Option<String>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    /// Service provider signing private key. Debug output is redacted.
49    pub private_key: Option<SecretString>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    /// Service provider decryption private key for encrypted assertions.
52    pub decryption_pvk: Option<SecretString>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    /// Additional AuthnRequest parameters sent to the IdP.
55    pub additional_params: Option<BTreeMap<String, serde_json::Value>>,
56}
57
58/// Backward-compatible SAML config alias.
59pub type SamlConfig = SamlProviderConfig;
60
61const fn default_want_assertions_signed() -> bool {
62    true
63}
64
65#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
66#[serde(rename_all = "camelCase")]
67/// IdP metadata fields accepted by SAML provider configuration.
68pub struct SamlIdpMetadata {
69    pub metadata: Option<String>,
70    #[serde(rename = "entityID", alias = "entityId")]
71    pub entity_id: Option<String>,
72    #[serde(rename = "entityURL", alias = "entityUrl")]
73    pub entity_url: Option<String>,
74    #[serde(rename = "redirectURL", alias = "redirectUrl")]
75    pub redirect_url: Option<String>,
76    pub cert: Option<String>,
77    pub private_key: Option<SecretString>,
78    pub private_key_pass: Option<SecretString>,
79    pub is_assertion_encrypted: Option<bool>,
80    pub enc_private_key: Option<SecretString>,
81    pub enc_private_key_pass: Option<SecretString>,
82    pub single_sign_on_service: Option<Vec<SamlService>>,
83    pub single_logout_service: Option<Vec<SamlService>>,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87/// SAML metadata service endpoint.
88pub struct SamlService {
89    #[serde(rename = "Binding")]
90    pub binding: String,
91    #[serde(rename = "Location")]
92    pub location: String,
93}
94
95#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97/// Service provider metadata overrides.
98pub struct SamlSpMetadata {
99    pub metadata: Option<String>,
100    #[serde(rename = "entityID", alias = "entityId")]
101    pub entity_id: Option<String>,
102    pub binding: Option<String>,
103    pub private_key: Option<SecretString>,
104    pub private_key_pass: Option<SecretString>,
105    pub is_assertion_encrypted: Option<bool>,
106    pub enc_private_key: Option<SecretString>,
107    pub enc_private_key_pass: Option<SecretString>,
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase")]
112/// Mapping from SAML attributes to RustAuth profile fields.
113pub struct SamlMapping {
114    pub id: Option<String>,
115    pub email: Option<String>,
116    pub email_verified: Option<String>,
117    pub name: Option<String>,
118    pub first_name: Option<String>,
119    pub last_name: Option<String>,
120    pub extra_fields: Option<BTreeMap<String, String>>,
121}