1#![allow(
7 deprecated,
8 reason = "the example keeps exercising the deprecated strict() preset"
9)]
10
11#[cfg(any(
12 feature = "crypto-rustcrypto",
13 feature = "crypto-aws-lc",
14 feature = "crypto-fips"
15))]
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 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 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 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}
98
99#[cfg(not(any(
100 feature = "crypto-rustcrypto",
101 feature = "crypto-aws-lc",
102 feature = "crypto-fips"
103)))]
104fn main() {
105 eprintln!("Enable a crypto provider feature (`crypto-bergshamra` is on by default).");
106}