Issue with SAML 2.0 single logout - How should IdP terminate SP sessions running in different user agents? - saml

I'm having an issue with SAML 2.0 single logout.
I have a SAML 2.0 environment with an IdP (identity provider) and a web application acting as SP (service provider).
As user I start a web application session in an user agent (browser). The user is authenticated using the IdP.
In a different browser (running on the same client machine) I start another session as the same user in the same web application, i.e. in the same SP in terms of SAML.
Now I have two independent web application sessions where the same user is authenticated.
When I then perform a single logout initiated by the IdP in one of the browsers the IdP issues only one logout request which terminates the session that is running in that browser. The element of the logout request issued by the IdP equals the one that was sent by the IdP in the attribute SessionIndex of the AuthnStatement of the Assertion sent to the SP using that browser (user agent).
Wouldn't it actually be necessary for the IdP to send logout requests for all open sessions in order to achieve a true "single logout"?

Short answer: The SAML spec allows for Single Logout (SLO) to behave the way you want but a typical implementation isn't that sophisticated.
From SAML Profiles spec, section 4.4 (Single Logout Profile):
Once a principal has authenticated to an identity provider, the
authenticating entity may establish a session with the principal
(typically by means of a cookie, URL re-writing, or some other
implementation-specific means). The identity provider may subsequently
issue assertions to service providers or other relying parties, based
on this authentication event; a relying party may use this to
establish its own session with the principal. In such a situation, the
identity provider can act as a session authority and the relying
parties as session participants.
If the SLO sequence were to be initiated by one of the session participants, this whole discussion would be moot. The spec requires the session participant to identify the "shared" session being terminated via a unique ID (aka session index) that was originally sent to the session participant by the identity provider. As required by the spec, this ID will be different in your SP session #1 vs SP session #2.
...but when the SLO sequence is initiated by the IdP, your scenario is possible. Section 4.4.4.1 talks about the rules around issuing and processing <LogoutRequest>:
If the requester is a session participant, it MUST include at least
one <SessionIndex> element in the request. [...] If the requester is a
session authority (or acting on its behalf), then it MAY omit any such
elements to indicate the termination of all of the principal's
applicable sessions
Translation: if you could somehow tell the IdP to issue a <LogoutRequest> without a <SessionIndex> and your SP is sophisticated enough to correctly interpret such request and the SP can terminate all sessions for a particular user via its backend, then you've won.
In reality, the combination of conditions above is a very tall order. Out of the box, most IdPs will not issue a <LogoutRequest> without a <SessionIndex>. The very few SPs that even bother implementing SLO will not accept a request without a <SessionIndex>. In an extremely rare case where you'll be able to come up with a correct <LogoutRequest> and SP won't choke on it, you'll be very, very lucky if the SP correctly identifies all IdP-initiated sessions AND will be able to terminate them via the backend.

Related

Does SAML SLO (Single Logout) logout from all SP (Service Provider)?

Our javaspring application (sp) allows SSO integration for the clients. We have planned to introduce SLO (Single Logout) as part of the security audit requirement.
I have a doubt, if our application request for SLO to idp then the particular customer's all other open app's get logged out ?
We don't want to make customer's other application get logged out due to our application.
Kindly advise. If the SAML SLO request will only impact the only the service provide which requests the logout or all the service provider which customer SSO logged in with?
Typically single-logout (SLO) will cascade from one SP to the IdP back to all related child sessions at the other SPs. Depending on what IdP you use, you may be able to control that / be more fine-grained but you have to be careful you're not opening yourself up to any attacks (on orphaned sessions).
As per SAML spec the IdP has to inform all other session participants.

SAML SSO: keeping users logged in after validating the SAML Assertion

I am implementing front-channel SAML 2.0 SSO golang Service Provider, with Okta as my Identity Provider (this is just a POC and should eventually work with any IdP).
Implementing the sign on process was straightforward with saml2 package. I've created the login endpoint that redirects to the SAML application login URL at the intended IdP, as well as the POST callback endpoint which is properly receiving the SAML assertion and is able to validate it. After that a session with a random cookie is created with the same TTL as the Identity Provider session TTL. So far everything works well (I haven't implemented Single Sign-Out yet, but I'm planning to).
However, when some time passes and the session expires, I'd like to renew it only if the user is still logged in with the Idp and hasn't been removed from the SAML Application. I would like to avoid redirecting the user to perform SSO again with IdP, because it would mean that if they are still logged in, they would be redirected back to the home page of my application. I wasn't able to find great sources on my options to go about it online.
Questions:
1.1 One solution that comes to mind is storing the requested URL in the RelayState parameter, whenever the session has expired, then redirect the user to the IdP SSO URL. When the redirect returns to the SAML callback POST endpoint, check the RelayState parameter and if set, redirect back to that (original) URL. That means that for users that use the system continuously, I would have to request Assertions very often. Does that make sense?
1.2 A second solution that comes to mind is to implement a back-channel of communicating directly from my SP to the IdP. That would allow me to verify a user is still logged in 'behind the users back'. If that's a sound idea:
a. Do I need to have dedicated code for each IdP?
b. Do I need to load an API key to the IdP which would allow secure communication?
c. Do I need to upload a public certificate to the IdP that would be able to verify that my SP signed the requests?
Will using the Assertion to get an OAuth 2.0 Access Token help me in achieving this?
I've chosen SAML 2.0 for now, since the environment is an enterprise oriented one and I thought it fits well with it based on what I read. Would using OpenID Connect instead help achieve my goals easier and fit well with enterprise oriented products?

Feasiblity of SAML

I have a scenario where I have four to five web based application, which needs to have a common centralized authentication system, in this case how feasible is the SAML based approach i.e each time user want to access any of these web application the user is redirected to SAML server which in return redirects to the IDP, or is their some better solution for such architecture as I am new to the this domain
What you describe is exactly what SAML is designed to solve.
The user is normally only redirected to the SAML Identity Provider (Idp) on the first access to an application (a service provider (SP)). When the user is successfully authenticated by the Idp, the SP sets a cookie in the user's browser to handle authentication of subsequent requests.

Informing SP about session invalidated in IDP

I was trying to use SAML through SSO,my question is when a session becomes invalid in IDP, how does IDP notifies this to SP, if I have multiple copy of SP sitting in geographically distributed region sitting behind a load balancer,how the message reaches a particular SP as the DNS name for all will be same.
Depends on specific IdP implementation. Some IdPs are using back channel. Sending SOAP message to inform all SP's that are in partner trust. OpenAM per instance is using this mechanism. Performing SLO request to all SP's.

How to get SAML assertion from OpenAM (using Java)?

I'm in the midst of finding some means (preferably through Java code) that will enable me to get the SAML assertion from the IDP (i.e. ForgeRock's OpenAM) for a Service Provider (SP) via SSO Login.
The SP have already been configured to interact with the IDP (e.g. vCloud Director --> OpenAM and vice versa) through a Web Browser (i.e. the user will be automatically redirected to the OpenAM login page upon invoking the vCloud Director login page). However, this process is only applicable through browsers (where redirection is provided) but not outside the browser.
I can't seem to find any means to perform SSO Login (by using the SAML assertion from the IDP for authentication). So far I've come across a dozen of references including the AssertionIDRequestUtil.sendAssertionIDRequestURI function from the OpenAM SSO, still, I'm not sure where to retrieve the AssertionId and SAML EntityId parameters.
Are there other means of getting the SAML assertion? Or maybe other ways to perform SSO Login?
I think the easiest way to achieve this would be:
perform authentication via REST or ClientSDK
use a Java HTTP client to kick off an IdP initiated SAML authentication flow (/openam/idpssoinit?metaAlias=/idp&spEntityID=entityID). When you send this request you need to make sure that:
the session id is part of the request as an iPlanetDirectoryPro cookie,
session upgrade won't be performed (your authcontext settings at the IdP will have a lower or equal authLevel, than the level the session was created with in the first step)