Skip to main content

raw_compat/
raw_compat.rs

1//! Low-level raw compatibility SSO example.
2//!
3//! New browser integrations should start with `examples/sso.rs`. This example
4//! is for callers that need direct access to raw `ServiceProvider`,
5//! `IdentityProvider`, `HttpRequest`, or `FlowResult` values.
6
7#[cfg(feature = "crypto-bergshamra")]
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    use saml_rs::constants::signature_algorithm::RSA_SHA256;
10    use saml_rs::raw::metadata::{Endpoint, IdpMetadataConfig, SpMetadataConfig};
11    use saml_rs::raw::{
12        Binding, EntitySetting, HttpRequest, IdentityProvider, LoginResponseOptions,
13        ServiceProvider, User,
14    };
15
16    let privkey = include_str!("../tests/fixtures/key/sp_privkey.pem");
17    let cert = include_str!("../tests/fixtures/key/sp_signing_cert.cer");
18    let signing = || {
19        let mut setting = EntitySetting::default();
20        setting.private_key = Some(privkey.into());
21        setting.signing_cert = Some(cert.into());
22        setting.request_signature_algorithm = RSA_SHA256.into();
23        setting
24    };
25
26    let idp = IdentityProvider::from_config(
27        &IdpMetadataConfig {
28            entity_id: "https://idp.example.com/metadata".into(),
29            signing_certs: vec![cert.into()],
30            want_authn_requests_signed: true,
31            single_sign_on_service: vec![Endpoint::new(
32                Binding::Post,
33                "https://idp.example.com/sso",
34            )],
35            ..Default::default()
36        },
37        signing(),
38    )?;
39    let sp = ServiceProvider::from_config(
40        &SpMetadataConfig {
41            entity_id: "https://sp.example.com/metadata".into(),
42            authn_requests_signed: true,
43            want_assertions_signed: true,
44            signing_certs: vec![cert.into()],
45            assertion_consumer_service: vec![Endpoint::new(
46                Binding::Post,
47                "https://sp.example.com/acs",
48            )],
49            ..Default::default()
50        },
51        signing(),
52    )?;
53
54    let request = sp.create_login_request(&idp, Binding::Post, None)?;
55    let parsed = idp.parse_login_request(
56        &sp,
57        Binding::Post,
58        &HttpRequest::post(vec![("SAMLRequest".into(), request.context.clone())]),
59    )?;
60    let response = idp.create_login_response(
61        &sp,
62        Binding::Post,
63        &User::new("alice@example.com"),
64        &LoginResponseOptions {
65            in_response_to: parsed.extract.get_str("request.id"),
66            ..Default::default()
67        },
68    )?;
69    let result = sp.parse_login_response_with_request_id(
70        &idp,
71        Binding::Post,
72        &HttpRequest::post(vec![("SAMLResponse".into(), response.context)]),
73        &request.id,
74    )?;
75    println!(
76        "raw compatibility authenticated = {:?}",
77        result.extract.get_str("nameID")
78    );
79    Ok(())
80}
81
82#[cfg(not(feature = "crypto-bergshamra"))]
83fn main() {
84    eprintln!("Enable the `crypto-bergshamra` feature (on by default) to sign and verify.");
85}