Skip to main content

Outbound

Struct Outbound 

Source
pub struct Outbound<Message> { /* private fields */ }
Expand description

Typed outbound browser action.

§Examples

use saml_rs::{AuthnRequest, Outbound};

let redirect = Outbound::<AuthnRequest>::try_from(redirect_context())?;
assert!(redirect.redirect_url()?.contains("SAMLRequest="));

let post = Outbound::<AuthnRequest>::try_from(post_context())?;
assert_eq!(post.post_form()?.action().as_str(), "https://idp.example.com/sso");

Implementations§

Source§

impl<Message> Outbound<Message>

Source

pub fn id(&self) -> &MessageId

Message ID.

Source

pub fn relay_state(&self) -> Option<&RelayState>

RelayState parameter, when present.

Source

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

Redirect URL for Redirect actions.

§Errors

Returns SamlError::UndefinedBinding when this action is not Redirect.

Source

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

POST form for POST and SimpleSign actions.

§Errors

Returns SamlError::UndefinedBinding when this action is Redirect.

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

pub fn raw_context(&self) -> &BindingContext

Raw compatibility context used to build this typed action.

Source

pub fn into_raw_context(self) -> BindingContext

Consume the typed action and return the raw compatibility context.

Trait Implementations§

Source§

impl<Message: Clone> Clone for Outbound<Message>

Source§

fn clone(&self) -> Outbound<Message>

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<Message: Debug> Debug for Outbound<Message>

Source§

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

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

impl TryFrom<BindingContext> for Outbound<AuthnRequest>

Source§

type Error = SamlError

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

fn try_from(raw_context: BindingContext) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl TryFrom<BindingContext> for Outbound<SsoResponse>

Source§

type Error = SamlError

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

fn try_from(raw_context: BindingContext) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl TryFrom<BindingContext> for Outbound<LogoutRequest>

Source§

type Error = SamlError

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

fn try_from(raw_context: BindingContext) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl TryFrom<BindingContext> for Outbound<LogoutResponse>

Source§

type Error = SamlError

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

fn try_from(raw_context: BindingContext) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl<Message> Freeze for Outbound<Message>

§

impl<Message> RefUnwindSafe for Outbound<Message>
where Message: RefUnwindSafe,

§

impl<Message> Send for Outbound<Message>
where Message: Send,

§

impl<Message> Sync for Outbound<Message>
where Message: Sync,

§

impl<Message> Unpin for Outbound<Message>
where Message: Unpin,

§

impl<Message> UnsafeUnpin for Outbound<Message>

§

impl<Message> UnwindSafe for Outbound<Message>
where Message: UnwindSafe,

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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