SAML spec: returning to the SP without a user - saml

I'm using the standard SAML 2.0 SP-initiated SSO protocol for authentication.
Normally the IdP returns a samlp:Response XML object to my SP, containing a saml:Assertion about the authenticated user.
Does the SAML spec allow the IdP to return a response to the SP that doesn't contain user information?
I'd like handle the situation where authentication couldn't be done, but we want to return to the SP's site. Maybe the IdP could return some kind of error or message to our SP? Right now it seems like if authentication is impossible, the user is stuck on the IdP's site.
I guess they could just redirect to an agreed-upon URL, although then you would lose the RelayState information. Would that be the right approach, or does the SAML spec handle this scenario?

The SAML2 spec handles this. The Idp can return a samlp:response with a status code of Responder meaning that the idp failed to fulfill the request. Then there can be more detailed status information on exactly why.
But the case where an Idp fails to authenticate the user can be handled in the protocol. However, I think that most Idps behave as you describe - keep the user on the Idp if things goes wrong.
Added by OP — this is from the SAML spec:
<StatusCode> [Optional]
A subordinate status code that provides more specific information on an error condition. Note that responders MAY omit subordinate status codes in order to prevent attacks that seek to probe for additional information by intentionally presenting erroneous requests.
The permissible top-level values are as follows:
urn:oasis:names:tc:SAML:2.0:status:Success
The request succeeded. Additional information MAY be returned in the and/or elements.
urn:oasis:names:tc:SAML:2.0:status:Requester
The request could not be performed due to an error on the part of the requester.
urn:oasis:names:tc:SAML:2.0:status:Responder
The request could not be performed due to an error on the part of the SAML responder or SAML authority.
urn:oasis:names:tc:SAML:2.0:status:VersionMismatch
The SAML responder could not process the request because the version of the request message was incorrect.

Related

How is a failed login attempt represented with SAML with SP-initiated SSO?

I would like to set up my Service Provider (SP) for SP-initiated SSO.
When the user successfully logs in, I'm expecting the IdP to POST a SAML Assertion to my SP (is this called endpoint on my SP called an Assertion Consumer Service?).
What should I expect to happen when my SP and IdP are configured correctly but the user fails to authenticate – either with their primary credentials or MFA? Will the IdP POST a failure message to my SP?
If so, what is the conventional terminology for this payload? Is it still called a SAML Assertion but containing some kind of failure syntax differences or is it a totally different type of SAML payload, called something else? Do both success and failure payloads get sent to the same SP endpoint?
Thank you!
The thing you get back from the Identity Provider is always a SAML Response. If it's a successful response, you get an assertion. If it's a failed response, you get an error message passed from the IdP... And there's no real "standard" for those responses, other than the typical SAML message formatting.
Section 3.5.6 of the Binding spec describes the expectation for the POST profile. Each profile will provide for this, but as the SP, in most situations, you'll be using this binding.
Section 3.2.2 of Core defines the StatusResponseType - effectively, the status code of response that should be sent in various situations, the status message and status detail. It should be noted that most IdPs will simply return the urn:oasis:names:tc:SAML:2.0:status:AuthnFailed status code, and then maybe some additional detail in the status message or detail fields... But you cannot count on more than the code.
And yes, responses will always go to the typical SAML protocol endpoint, no matter their status.

Is it possible to tie initial SAML request to the SAML Assertion received from the IDP?

I am looking for a way to tie the SAML request I make to an IDP to the SAML Assertion it sends back. Is there a way to do that?
One idea I had was to use the SessionIndex. I have found that in practice, in some cases the SessionIndex can be used to do this, because some SAML servers return the ID from the initial request as the SessionIndex in the SAML Assertion, but I have also found that is not done universally / does not seem to be required by the spec. It seems like the intention of the SessionIndex is just to tie together the SAML Assertion with subsequent calls, e.g. logout attempts, so there's no requirement that it be tied to the initial request. I draw that conclusion from this post, which says "At least one assertion containing an MUST contain a element with at least one element containing a Method of urn:oasis:names:tc:SAML:2.0:cm:bearer. If the identity provider supports the Single Logout profile, defined in Section 4.4, any such authentication statements MUST include a SessionIndex attribute to enable per-session logout requests by the service provider." I have also reviewed this post, which breaks down the use of SessionIndex and I think supports the same conclusion.
I don't see anything else in the spec that seems promising, but I am hoping I may be missing something - is there any reliable way to pass data to the IDP in a SAML request and get it back in the SAML Assertion?
FYI, the reason why I want this is to support mobile sso login where my mobile device uses an embedded web browser to make an OAuth2 call to my web server, the web server authenticates the user, and then sends back an authorization code to the mobile device with a redirect. I want to use PKCE to secure the OAuth2 flow between the mobile device and the web server, but that requires me to be able to tie the initial request call to the final redirect with a shared code.
There are at least two methods that can be used, so long as the user journey starts where it should, on the page they are trying to get to, making this a service-provider initiated authentication request. As the service provider in a SAML-based federation, you start the process by sending the identity provider an AuthnRequest.
The first method availables comes by tracking the AuthnRequest's ID. In a good SAML implementation, that AuthnRequest's ID is big and random and likely not repeatable in our lifetime. The SAML Profiles spec says on lines 625-626:
If the containing message is in response to an <AuthnRequest>, then
the InResponseTo attribute MUST match the request's ID.
Therefore, as long as you keep track of the ID's that you send out, then you can tie the Request's ID to the Response's inResponseTo.
The second method at your disposal is RelayState. This is an aptly-named element of an AuthnRequest that you can use to transfer state to the Identity Provider an back. This is a field that you can use as you see fit as the service provider, and the responder has to send it back. The Bindings spec says on lines 265-271:
Some bindings define a "RelayState" mechanism for preserving and
conveying state information. When such a mechanism is used in
conveying a request message as the initial step of a SAML protocol, it
places requirements on the selection and use of the binding
subsequently used to convey the response. Namely, if a SAML request
message is accompanied by RelayState data, then the SAML responder
MUST return its SAML protocol response using a binding that also
supports a RelayState mechanism, and it MUST place the exact
RelayState data it received with the request into the corresponding
RelayState parameter in the response.
As such, you can put something in that field, and the IdP must parrot it back untouched. You should make sure that what you put in there doesn't compromise the user or security, so just be mindful of how you use it. It's going to end up in logs somewhere.

Should AuthnStatement be present in IdP initiated SAMLResponse

In the case of IDP Initiated FLow, Is the AuthnStatement is also mandatory in Assertion of the SAML Response?
Edit:
And what is bearer Assertion and what is its use?
As far as we are talking about the Authentication Request Protocol which is used in Web Browser SSO Profile for both SP and IDP initialized single sign-on, the standard has the followng to say:
In case profile doesn't override) The assertion(s)
returned MUST contain a element that represents the
presenter. The identifier type and format are determined by the
identity provider. At least one statement in at least one assertion
MUST be a that describes the authentication
performed by the responder or authentication service associated with
it. (2250-2253 core)
and
The set of one or more assertions MUST contain at least one
that reflects the authentication of the principal to
the identity provider. (547-548 profiles)
So the answer is - depends on profile, some SAML profiles (including custom ones) may not require AuthnStatements, but the most typical SAML profile for web single sign-on (and the one you are most likely talking about) does require it for both SP and IDP initialized flow.
And to your second question - bearer assertion is such assertion which is using bearer subject confirmation.
Subject confirmation is piece of information which helps recipient of the assertion (relying party / service provider) verify that the presenter of the assertion (attesting party - e.g. browser, or API client, ...) is associated with its subject (about whom was the assertion issued) and authorized to present the assertion on subject's behalf (to make sure that someone cannot use assertion issued for someone else, without someone else's permission). The bearer subject confirmation simply means that the presenter of the assertion is the same as the subject.
Few things are mandatory in SAML. Accordning to SAML AuthnStatement is not mandatory in any assertion. This is probably constrained in some way in the software you are using. If it is mandatory for Assertions in SP init flow I would guess it is mandatory in the IDP init flow to

Are SAML tokens cache/stored anywhere on the browser?

Scenario:
Browser(User) requests resource from Service Provider (SP).
SP Redirects (with SAML Request) to Identity Provider (IdP).
Since it is first login, User gives the (IdP) his/her valid credentials.
IdP then redirects Browser (with SAML Response which includes SAML token) to the SP page.
I have two questions:
A. In Step 4, does the Browser store or cache the SAML Response and/or SAML token?
B. If yes, what kind of things (attributes? timeouts? protocols?) prevent me from taking that stored SAML token. Then coping it over to another computer (with a new session) and using that token to Login to the same SP?
The answer is "sort of" re caching. In your scenario, the Response will be sent via POST to the Service Provider from the browser. So the browser can "cache" the POST data that contains the SAML Response. So, just like any other POST event in browsers, if the user were to use the back button enough times after logging into the SP to get back to the POST event, the POST data could be resent to the SP.
There are a few things that help keep the Response from being hijacked -
Use of HTTPS between all parties
SP enforcement of NotBefore & NotOnOrAfter attributes
SP enforcement of one time use criteria (the SP must ensure that Response is not re-used during its validity period. If the message is received outside the validity window, then the SP should discard the message)
The IDP usually stores a session cookie on the client browser identifying the SAML session. The theft of this session cookie is probably no more protected then any other session cookie.
Using HTTPS in communication between SP and IDP will provide a great deal of protection from session hijacking.
For question A, it probably depends on the browser that you use.
For question B, there are several mechanisms that prevent the SAML response from being reused:
SubjectConfirmationData has attribute NotBefore and NotOnOrAfter that specify the time frame that the SAML assertion is valid. Thus, the SAML assertion cannot be used outside of this time frame.
SubjectConfirmationData has attribute InResponseTo that specifies the SAML request for which the SAML assertion is issued. Thus, the SAML assertion cannot be used for other SAML request.
SP must ensure that the SAML assertion is not replayed by maintaining a set of used SAML assertion.
You can read Section 4.1.4.3 and 4.1.4.5 of SAML Profiles specification.
I know this old, but the answer is yes the browser stores the SAML Token as a Cookie. (Typically) You can see it in your Browser's Cookie list, through various traffic/session inspectors like Fiddler, SAML Tracer on FF etc.

How should I be implementing the HTTP POST Protocol Binding for SAML WebSSO Profile?

I've implemented my Service Provider and Identify Provider following the SAML Profile for Web SSO using HTTP POST Protocol Binding. However, I am a bit confused as to how the Identity Provider will provide an <AuthnStatement> if the HTTP POST coming from the Service Provider is not tied to a session on the Identity Provider.
Could someone enlighten me how one would be able to do this?
The other approach I could use is the HTTP Redirect Binding, but that requires User-Agent intervention (i.e., the browser), often using the User-Agent simply as a pass-thru intermediary to faciliate the Request-Response message exchange. I'd rather use HTTP POST for this reason, because the message exchange occurs server-side, so the user sees nothing happening on their screen.
However, using HTTP Redirect makes more sense to me with respect to how I'd be able to tie a session to a request. Since the HTTP Redirect is facilitated via a User-Agent, the request to the IdP will have a session (if previously authenticated). What I don't get though is how to send an <AuthnRequest> on a HTTP Redirect. Answered by JST
So I'm a bit confused and would love to hear what other people are doing. Here are my questions again:
Using the HTTP POST Protocol Binding with the IsPassive option the <AuthnRequest>, how do I tie a request made by the Service Provider to a session on the Identity Provider? In other words, how does the Identity Provider know who is making the request if the POST is coming from the Service Provider which is technically an anonymous session?
Using the HTTP Redirect Protocol Binding, how do I send an <AuthnRequest> to the Identity Provider if I am using a HTTP Redirect? Answered by JST
UPDATE
Sorry for the confusion if I was unclear in my explanation above. I am implementing both the IdP and SP (via a plugin). The IdP is an existing application for which I want the SP (a third-party system) to use for authentication (i.e., Web SSO). I am developing a simple PoC at the moment. The SP is actually a third-party Spring application for which I am developing a plugin to perform the SAML operations.
I should have mentioned that I am trying to do this using the IsPassive option, that meaning the User-Agent doesn't come into play during the message exchange. It is simply the catalyst that gets the SAML-party started. Right? With that in mind, given that the user is anonymous at Step 1, what does the SP send to the IdP to allow the IdP figure out whether the user is already authenticated? Because of IsPassive, the HTTP POST isn't sent via the User-Agent
UPDATE
Question 1 Revised: How does the IdP resolve the Principal when the AuthnRequset is sent with the IsPassive option on?
Straight from the SAML 2.0 Profiles document, page 15, lines 417 to 419:
In step 4, the principal is identified
by the identity provide by some means
outside the scope of this profile.
What I'm really after is an explanation how to implement some means.
The thing to keep in mind is that there's no connection between a session on the IdP and a session on the SP. They don't know about each other, and communicate only through the SAML messages. The general steps for SP-initiated SAML SSO are:
Anonymous user visits resource (page) at SP.
SP identifies that user needs to be authenticated at IdP.
SP constructs AuthnRequest and sends to IdP.
IdP does some sort of authentication, constructs SAML Response and sends to SP.
SP validates Response and, if valid, does whatever is necessary to identify user at SP and get them to originally requested resource.
Yes, there does need to be some way to connect the SP's AuthnRequest to the IdP's Response. That's covered by the SAML spec: the SP's AuthnRequest includes an ID value, and the corresponding response from the IdP MUST include an InResponseTo attribute (on its SubjectConfirmationData element) with that ID value. The Authentication Request Protocol also allows the SP to pass a RelayState parameter to the IdP, which the IdP is then REQUIRED to pass along unchanged with the SAML Response. You (in the SP role) can use that RelayState value to capture state information allowing the user to be relayed to the originally requested resource.
That implies that when you implement an SP, you'll need some mechanism for recording ID and RelayState values, and your Response processing needs to validate InResponseTo and RelayState values it receives. How you choose to create and interpret RelayState values is up to you, but keep in mind that there is a length limit. (We use random GUID values corresponding to locally saved state data, which has the extra advantage of not giving any hint of meaning to the RelayState values.)
How does the IdP know who is making the request? The AuthnRequest must include an Issuer element that identifies the SP. It might also contain an AssertionConsumerServiceURL (the URL to which the Response is to be sent), or the IdP may have a local mapping of the Issuer to the proper URL.
How do you send an AuthnRequest using HTTP Redirect? The only difference between AuthnRequest sent using POST vs. Redirect, besides using GET rather than POST, is that the AuthnRequest XML has to get compressed (using the DEFLATE encoding).
Hope that answers most of your questions.
John,
I might suggest taking a step back and doing some more research before you decide to write your own SAML IDP/SP Implementation. You appear to be mixing Bindings with Profiles, Unsolicited vs Solicited Web SSO as well as the fact that SAML requires that the User Agent (aka Browser) is the bearer of almost all the messages between the IDP and SP. There is also a ton of info in the spec that will will have to implement to ensure your solution is actually secure.
I would suggest starting with our SAML Knowledge Base and then moving on to the OASIS SAML 2.0 Technical Overview for information on these flows.
Alternatively, if you decide to go best-of-breed you can check out our PingFederate product which can enable ALL the SAML IDP/SP use cases for you in < a day.
Hope this helps -
Ian
Unlike Ian, I am not associated with a company producing SAML-related products. However, I'd give somewhat similar advice: step back and identify why you are implementing SP or IdP. Are you really acting as both SP and IdP, or are you really just one or the other? If you're implementing/acting as IdP only, then it's fairly likely that a product like PingFederate or something similar offers all you need through configuration rather than requiring you to write custom code. If you're implementing SP, then such a product MAY be able to help you out, but it depends to a large extent on the characteristics of the system you're integrating it into. I am speaking as a developer who has done both IdP and SP implementations, and evaluated several tools before determining that because of our specific system, clients, and requirements, a custom implementation was our best option. It's been in place for over a year, with several clients using it (including some using varying commercial IdP tools).
If you can identify your use cases in terms of SAML profiles/bindings, then you'll be better equipped to make a buy-vs-build decision.