pub struct ServiceProvider {
pub setting: EntitySetting,
pub metadata: SpMetadata,
}Expand description
Compatibility export for older crate-root imports. Use Saml for new integrations; advanced raw callers should import raw::ServiceProvider.
A SAML 2.0 Service Provider: runtime EntitySetting plus parsed SpMetadata.
Fields§
§setting: EntitySettingRuntime configuration (keys, algorithms, flags).
metadata: SpMetadataParsed SP metadata.
Implementations§
Source§impl ServiceProvider
impl ServiceProvider
Sourcepub fn from_metadata(
xml: &str,
setting: EntitySetting,
) -> Result<Self, SamlError>
pub fn from_metadata( xml: &str, setting: EntitySetting, ) -> Result<Self, SamlError>
Build from SP metadata XML, merging the metadata-declared flags into setting.
§Errors
Returns an error when xml is malformed, exceeds XML limits, or cannot
be parsed as SP metadata. Metadata parser errors include invalid entity,
endpoint, certificate, or signing flag declarations.
Sourcepub fn from_config(
config: &SpMetadataConfig,
setting: EntitySetting,
) -> Result<Self, SamlError>
pub fn from_config( config: &SpMetadataConfig, setting: EntitySetting, ) -> Result<Self, SamlError>
Build by generating SP metadata from config, then importing it.
§Errors
Returns an error if the generated metadata cannot be parsed back into SP metadata, including invalid endpoint or certificate declarations.
Examples found in repository?
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}Sourcepub fn metadata_xml(&self) -> &str
pub fn metadata_xml(&self) -> &str
The SP metadata XML.
Sourcepub fn create_login_request(
&self,
idp: &IdentityProvider,
binding: Binding,
custom: Option<CustomTagReplacement<'_>>,
) -> Result<BindingContext, SamlError>
pub fn create_login_request( &self, idp: &IdentityProvider, binding: Binding, custom: Option<CustomTagReplacement<'_>>, ) -> Result<BindingContext, SamlError>
Build a login <AuthnRequest> for idp over binding.
When both sides require signing, the request is signed (requires the
crypto-bergshamra feature and the SP’s private_key/signing_cert).
custom overrides template rendering, receiving the resolved template
and returning (id, xml).
§Errors
Returns an error if SP and IdP signing requirements conflict, the IdP
metadata has no SSO endpoint for binding, the SP metadata has no ACS
endpoint for the requested response binding, or binding is unsupported
for AuthnRequest generation. When signing is required, key loading,
missing private_key/signing_cert, unsupported crypto features, XML
signature construction, and detached-signature construction errors are
propagated.
Examples found in repository?
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}Sourcepub fn create_login_request_with_options(
&self,
idp: &IdentityProvider,
binding: Binding,
options: &LoginRequestOptions<'_>,
) -> Result<BindingContext, SamlError>
pub fn create_login_request_with_options( &self, idp: &IdentityProvider, binding: Binding, options: &LoginRequestOptions<'_>, ) -> Result<BindingContext, SamlError>
Build a login <AuthnRequest> for idp over binding with per-call options.
§Errors
Returns an error if SP and IdP signing requirements conflict, the IdP
metadata has no SSO endpoint for binding, the SP metadata has no ACS
endpoint for options.response_binding when ACS index mode is not used,
or binding is unsupported. When signing is required, key loading,
missing private_key/signing_cert, unsupported crypto features, XML
signature construction, and detached-signature construction errors are
propagated.
Sourcepub fn parse_login_response(
&self,
idp: &IdentityProvider,
binding: Binding,
request: &HttpRequest,
) -> Result<FlowResult, SamlError>
pub fn parse_login_response( &self, idp: &IdentityProvider, binding: Binding, request: &HttpRequest, ) -> Result<FlowResult, SamlError>
Parse and validate an unsolicited IdP login <Response> (signature required).
This mode is for IdP-initiated SSO. It rejects a non-empty
InResponseTo; for SP-initiated SSO use
Self::parse_login_response_with_request_id to bind the response to
the AuthnRequest ID you issued.
When setting.validate_audience is set, the assertion’s <Audience>
must include this SP’s entity ID.
§Errors
Returns an error for all unsolicited-response validation failures from
Self::parse_unsolicited_login_response, including malformed browser
input, unsupported bindings, missing ACS metadata, XML parsing failures,
missing or invalid signatures, untrusted signing certificates, issuer,
destination, recipient, audience, status, time-window, and unexpected
InResponseTo failures.
Sourcepub fn parse_unsolicited_login_response(
&self,
idp: &IdentityProvider,
binding: Binding,
request: &HttpRequest,
) -> Result<FlowResult, SamlError>
pub fn parse_unsolicited_login_response( &self, idp: &IdentityProvider, binding: Binding, request: &HttpRequest, ) -> Result<FlowResult, SamlError>
Parse and validate an IdP-initiated login <Response> that is not bound
to an outbound AuthnRequest.
§Errors
Returns an error if the SP metadata has no ACS endpoint for binding,
binding is unsupported, the request is missing required binding
parameters, the SAML payload cannot be base64/DEFLATE decoded, XML
parsing or extraction fails, the status is not success, the required
signature is missing or invalid, no trusted IdP signing key is available,
or issuer, destination, bearer recipient, audience, subject-confirmation,
or time-window validation fails. Because this path is unsolicited, any
non-empty response or bearer InResponseTo also returns an error.
Sourcepub fn parse_login_response_with_request_id(
&self,
idp: &IdentityProvider,
binding: Binding,
request: &HttpRequest,
request_id: &str,
) -> Result<FlowResult, SamlError>
pub fn parse_login_response_with_request_id( &self, idp: &IdentityProvider, binding: Binding, request: &HttpRequest, request_id: &str, ) -> Result<FlowResult, SamlError>
Like Self::parse_login_response but also requires InResponseTo to
equal request_id (anti-replay: bind the response to a request you sent).
An empty caller-provided request_id is rejected as
SamlError::InvalidInResponseTo. A non-empty request_id that does
not match the SAML response returns SamlError::InResponseToMismatch.
§Errors
Returns an error if request_id is empty, the SP metadata has no ACS
endpoint for binding, binding is unsupported, the request is missing
required binding parameters, the SAML payload cannot be base64/DEFLATE
decoded, XML parsing or extraction fails, the status is not success, the
required signature is missing or invalid, no trusted IdP signing key is
available, or issuer, destination, bearer recipient, audience,
InResponseTo, subject-confirmation, or time-window validation fails.
Examples found in repository?
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}Trait Implementations§
Source§impl Clone for ServiceProvider
impl Clone for ServiceProvider
Source§fn clone(&self) -> ServiceProvider
fn clone(&self) -> ServiceProvider
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more