Skip to main content

SpConfig

Struct SpConfig 

Source
pub struct SpConfig {
    pub entity_id: EntityId,
    pub metadata: SpMetadataConfig,
    pub credentials: Credentials,
    pub validation: SpValidationPolicy,
    pub algorithms: AlgorithmPolicy,
    pub xml: XmlPolicy,
    pub templates: TemplatePolicy,
}
Expand description

Typed Service Provider configuration.

§Examples

use saml_rs::{AcsEndpoint, EntityId, SpConfig, SpMetadataConfig};

let acs = AcsEndpoint::post("https://sp.example.com/acs")?;
let config = SpConfig::try_new(
    EntityId::try_new("https://sp.example.com/metadata")?,
    SpMetadataConfig::new(vec![acs]),
)?;

assert_eq!(config.entity_id.as_str(), "https://sp.example.com/metadata");

Fields§

§entity_id: EntityId

Local SP entity ID.

§metadata: SpMetadataConfig

Local SP metadata inputs.

§credentials: Credentials

Local credentials.

§validation: SpValidationPolicy

Validation and outbound signing policy.

§algorithms: AlgorithmPolicy

Algorithm policy.

§xml: XmlPolicy

XML parser, redirect, clock, and encryption policy.

§templates: TemplatePolicy

Template and prefix policy.

Implementations§

Source§

impl SpConfig

Source

pub fn new(entity_id: EntityId, metadata: SpMetadataConfig) -> Self

Create SP configuration with required identity and metadata inputs.

This convenience constructor accepts already-validated typed inputs but does not validate the final config. Use Self::try_new or Self::builder for caller-provided setup.

Source

pub fn try_new( entity_id: EntityId, metadata: SpMetadataConfig, ) -> Result<Self, SamlError>

Validate and create SP configuration with the legacy permissive preset.

§Errors

Returns SamlError when the entity ID is empty or required SP metadata endpoints are missing.

Source

pub fn builder(entity_id: EntityId) -> SpConfigBuilder

Start a dependency-free SP config builder.

The builder starts on the deprecated SpValidationPolicy::strict bundle. Self::try_new uses SpValidationPolicy::compatibility.

Examples found in repository?
examples/sso.rs (line 37)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    use saml_rs::{
18        AcsEndpoint, AuthnRequest, BrowserInput, CertificatePem, Credentials, EntityId, IdpConfig,
19        IdpDescriptor, IdpValidationPolicy, MetadataTrustPolicy, NameId, PrivateKeyPem,
20        RelayStateParam, ReplayPolicy, RespondSso, Saml, SamlValidationContext, SpConfig,
21        SpDescriptor, SpValidationPolicy, SsoEndpoint, SsoResponse, StartSso, Subject,
22    };
23    use std::time::SystemTime;
24
25    let privkey = include_str!("../tests/fixtures/key/sp_privkey.pem");
26    let cert = include_str!("../tests/fixtures/key/sp_signing_cert.cer");
27    let credentials = || Credentials {
28        signing_key: Some(PrivateKeyPem::new(privkey)),
29        signing_certificate: Some(CertificatePem::new(cert)),
30        ..Credentials::default()
31    };
32    // DisabledForCompatibility preserves the raw API, which has no replay cache.
33    let validation =
34        || SamlValidationContext::new(SystemTime::now(), ReplayPolicy::DisabledForCompatibility);
35
36    let sp = Saml::sp(
37        SpConfig::builder(EntityId::try_new("https://sp.example.com/metadata")?)
38            .acs_endpoint(AcsEndpoint::post("https://sp.example.com/acs")?)
39            .credentials(credentials())
40            .validation(SpValidationPolicy::strict())
41            .build()?,
42    )?;
43    let idp = Saml::idp(
44        IdpConfig::builder(EntityId::try_new("https://idp.example.com/metadata")?)
45            .sso_endpoint(SsoEndpoint::post("https://idp.example.com/sso")?)
46            .credentials(credentials())
47            .validation(IdpValidationPolicy::strict())
48            .build()?,
49    )?;
50
51    let sp_descriptor = SpDescriptor::from_metadata_xml_for(
52        EntityId::try_new("https://sp.example.com/metadata")?,
53        sp.metadata_xml(),
54        // UnsignedForCompatibility preserves an unsigned samlify-port metadata import.
55        MetadataTrustPolicy::UnsignedForCompatibility,
56    )?;
57    let idp_descriptor = IdpDescriptor::from_metadata_xml_for(
58        EntityId::try_new("https://idp.example.com/metadata")?,
59        idp.metadata_xml(),
60        // UnsignedForCompatibility preserves an unsigned samlify-port metadata import.
61        MetadataTrustPolicy::UnsignedForCompatibility,
62    )?;
63
64    let relay_state = RelayStateParam::try_from_option(Some("demo-state".to_string()))?;
65    let started = sp.start_sso(&idp_descriptor, StartSso::post().relay_state(relay_state))?;
66    println!(
67        "SP  -> AuthnRequest id = {}",
68        started.pending.request_id().as_str()
69    );
70
71    let request = idp.receive_sso(
72        &sp_descriptor,
73        BrowserInput::<AuthnRequest>::post(started.outbound.post_form()?.fields().to_vec()),
74        validation(),
75    )?;
76    println!(
77        "IdP <- request issuer  = {}",
78        request.message().issuer().as_str()
79    );
80
81    let response = idp.respond_sso(
82        &sp_descriptor,
83        &request,
84        Subject::new(NameId::new("alice@example.com", None), Vec::new()),
85        RespondSso::post(),
86    )?;
87
88    let session = sp.finish_sso(
89        &idp_descriptor,
90        &started.pending,
91        BrowserInput::<SsoResponse>::post(response.post_form()?.fields().to_vec()),
92        validation(),
93    );
94    let session = session?;
95    println!("SP  <- authenticated   = {}", session.name_id().value());
96    Ok(())
97}
More examples
Hide additional examples
examples/slo.rs (line 37)
15fn main() -> Result<(), Box<dyn std::error::Error>> {
16    use saml_rs::{
17        AcsEndpoint, AuthnRequest, BrowserInput, CertificatePem, Credentials, EntityId, IdpConfig,
18        IdpDescriptor, IdpValidationPolicy, LogoutRequest, LogoutResponse, MetadataTrustPolicy,
19        NameId, PrivateKeyPem, ReplayPolicy, RespondSlo, RespondSso, Saml, SamlValidationContext,
20        SloEndpoint, SpConfig, SpDescriptor, SpValidationPolicy, SsoEndpoint, SsoResponse,
21        StartSlo, StartSso, Subject,
22    };
23    use std::time::SystemTime;
24
25    let privkey = include_str!("../tests/fixtures/key/sp_privkey.pem");
26    let cert = include_str!("../tests/fixtures/key/sp_signing_cert.cer");
27    let credentials = || Credentials {
28        signing_key: Some(PrivateKeyPem::new(privkey)),
29        signing_certificate: Some(CertificatePem::new(cert)),
30        ..Credentials::default()
31    };
32    // DisabledForCompatibility preserves the raw API, which has no replay cache.
33    let validation =
34        || SamlValidationContext::new(SystemTime::now(), ReplayPolicy::DisabledForCompatibility);
35
36    let sp = Saml::sp(
37        SpConfig::builder(EntityId::try_new("https://sp.example.com/metadata")?)
38            .acs_endpoint(AcsEndpoint::post("https://sp.example.com/acs")?)
39            .slo_endpoint(SloEndpoint::post("https://sp.example.com/slo")?)
40            .credentials(credentials())
41            .validation(SpValidationPolicy::strict())
42            .build()?,
43    )?;
44    let idp = Saml::idp(
45        IdpConfig::builder(EntityId::try_new("https://idp.example.com/metadata")?)
46            .sso_endpoint(SsoEndpoint::post("https://idp.example.com/sso")?)
47            .slo_endpoint(SloEndpoint::post("https://idp.example.com/slo")?)
48            .credentials(credentials())
49            .validation(IdpValidationPolicy::strict())
50            .build()?,
51    )?;
52    let sp_descriptor = SpDescriptor::from_metadata_xml_for(
53        EntityId::try_new("https://sp.example.com/metadata")?,
54        sp.metadata_xml(),
55        // UnsignedForCompatibility preserves an unsigned samlify-port metadata import.
56        MetadataTrustPolicy::UnsignedForCompatibility,
57    )?;
58    let idp_descriptor = IdpDescriptor::from_metadata_xml_for(
59        EntityId::try_new("https://idp.example.com/metadata")?,
60        idp.metadata_xml(),
61        // UnsignedForCompatibility preserves an unsigned samlify-port metadata import.
62        MetadataTrustPolicy::UnsignedForCompatibility,
63    )?;
64
65    let sso = sp.start_sso(&idp_descriptor, StartSso::post())?;
66    let request = idp.receive_sso(
67        &sp_descriptor,
68        BrowserInput::<AuthnRequest>::post(sso.outbound.post_form()?.fields().to_vec()),
69        validation(),
70    )?;
71    let response = idp.respond_sso(
72        &sp_descriptor,
73        &request,
74        Subject::new(NameId::new("alice@example.com", None), Vec::new()),
75        RespondSso::post(),
76    )?;
77    let session = sp.finish_sso(
78        &idp_descriptor,
79        &sso.pending,
80        BrowserInput::<SsoResponse>::post(response.post_form()?.fields().to_vec()),
81        validation(),
82    )?;
83
84    let subject = session
85        .logout_subject()
86        .ok_or("session has no logout subject")?;
87    let logout = sp.start_slo(&idp_descriptor, subject, StartSlo::post())?;
88    println!("SP  -> LogoutRequest id = {}", logout.pending.id().as_str());
89
90    let logout_request = idp.receive_slo(
91        &sp_descriptor,
92        BrowserInput::<LogoutRequest>::post(logout.outbound.post_form()?.fields().to_vec()),
93        validation(),
94    )?;
95    let logout_response = idp.respond_slo(
96        &sp_descriptor,
97        &logout_request,
98        RespondSlo::post().relay_state(logout.pending.relay_state().clone()),
99    )?;
100    let completed = sp.finish_slo(
101        &idp_descriptor,
102        &logout.pending,
103        BrowserInput::<LogoutResponse>::post(logout_response.post_form()?.fields().to_vec()),
104        validation(),
105    )?;
106    println!(
107        "SP  <- LogoutResponse status = {}",
108        completed.status().unwrap_or("missing")
109    );
110    Ok(())
111}
Source

pub fn validate(&self) -> Result<(), SamlError>

Validate required SP config fields.

§Errors

Returns SamlError when the entity ID is empty or required SP metadata endpoints are missing.

Trait Implementations§

Source§

impl Clone for SpConfig

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SpConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl TryFrom<&SpConfig> for EntitySetting

Source§

type Error = SamlError

The type returned in the event of a conversion error.
Source§

fn try_from(config: &SpConfig) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V