SSO - how exactly does the site performing authentication notify the site originally accessed that the user is successfully authenticated? - single-sign-on

I'm having hard time understanding SSO. Anywhere I read there are those high-level explanations of how the site that authenticates the user "passes the token" to the site that was originally accessed or that it knows that the user has already been authenticated if you access it later on. But I am still interested in the details of how those things are being accomplished.
Let's assume there are two sites, A and B, and a site X that is responsible for the authentication that A and B use.
Here are some questions that I can't find answers for:
if I access A and are then redirected to X to input my credentials, I get authenticated and then how exactly does X let A know that I am who I am? I know there is a token involved - how is this token passed exactly? Is it passes in a query string/body/header of a request that redirects me back to site A?
What happens after the A is notified that I have been authenticated? Does it issue me a cookie? Or am I holding this token somehow? How do A know with every subsequent request that I am who I am?
if I got successfully authenticated accessing site A and then try to access site B, I get redirected to site X - how does the site X know that I have already been authenticated? I guess I don't pass any cookies, do I? Did I get a cookie from X when authenticating there?

The reason it's confusing has to do with ambiguity of term "SSO". Your questions are good but the answers would depend on how SSO is implemented, there's not a one size fits all solution. We'll answer your questions with SAML as the protocol, it's often used to implement SSO between web apps:
A = service provider, X = identity provider. These are "roles" a service (or an application) might play in SAML. The identity provider sends a SAML response to the service provider after the identity provider authenticates the user. A so-called binding is a set of rules in SAML spec that determines how the response is formatted and transmitted from identity provider to the service provider. In Web Browser SSO profile of SAML, the HTTP-POST binding mandates that the response is sent via, well, POST over HTTPS. The response contains an assertion, sometimes referred to as a SAML "token". The assertion is a container for statements (aka claims) made by the SAML authority (your X) with respect to authenticated entity. For example, if the identity provider authenticates user "bee", the assertion sent to the service provider may contain bee's first name, last name, user id and so on.
Typically you'll get a cookie. The service provider A will create a "local" (to A) session and drop a cookie with session ID (or whatever session pointer) to associate the user agent with the session. On subsequent requests to A, A knows you on the basis of the cookie which maps to a session in A. The session holds the authenticated context established, say, the user id of user "bee" that came from the SAML response in step 1.
Also via cookies (usually). When you're authenticated with the identity provider X, it issues its own cookie. You have one cookie for X, one for A, one for B, ...
We say "usually" because the state management (how does A or X know it's you) is not part of the SAML spec. If an identity provider comes up with an exotic state management scheme, say, fingerprinting your browser and relying on that fingerprint as your authenticated context/session id, that's still okay with SAML from a protocol perspective. Only step 1 is formally described in the protocol, steps 2 and 3 are up to the implementation. In practice, cookies have a very short list of alternatives and most apps use cookies.
Take a look at SAML Technical Overview, it does a good job of addressing the essence of this Q&A.

Related

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?

SAML SSO how does it work?

Let's say we have a service provider app called A hosted on tomcat, a user clicks a link to the SP A. SP A sees no token is provided so it redirects the user to the IdP for authentication (with a SAML Authn request provided by some means). The IdP then redirects the user to some common login page where credentials are provided, assuming that these credentials are correct the IdP creates a SAML response with a token and some assertions about the subject, and sends it back to SP A. SP A sees this and allows the user access into the application. Great!
I have a few questions though
How is the authorisation request/response sent, I understand there is a redirect binding and a POST binding where the SAMLResponse and request are encoded either as a query param, or sent as an XHTML form in case of a POST binding. But I'm not sure which is used where?
A service provider is the thing providing a service, so Office 365 or Sales force for example. Is each one a separate service provider? I ask as I watched a video where the guy said the service provider was the thing that hosted these services, so I'm not sure of the correct answer here?
How is the token stored on the client side? So for example I am now authenticated against SP A, the user then tries to use SP B from the same machine/browser window, how does SP B and the IdP know that the user has already authenticated and therefore doesn't need to re-authenticate. I.e. the SSO aspect of it.
Does SP B need to be hosted on the same tomcat instance for this to work?
I dedicated significant time to get SSO working for me. The most helpful document was this specification
The answers below are based on this experience:
Redirect or Post binding is used depending on a respective HTTP request header. The Post binding is recommended since it does not imply restrictions on data volume transferred.
A Service Provider in this context is anything that clients request. There may be many of them, participating in the same SSO scheme.
The service providers must be SSO-aware, which includes handling of the authentication response data. Usually you don't have to implement the protocol - there are ready-made frameworks that your SP can utilize.
Service Providers may reside on different servers.
From my own experience:
You choose your own SAMLBinding (redirect or post) depending on what your idp and sp supports. This binding type will be used both for the 1st step (SP -> Idp) and 2nd step (IdP -> SP). If you have some running environment, open your browser devtools and look at network tab to see what happens. It's just a way to send data from browser to SP/IdP.
Both Office 365 and Salesforce.com are cloud services, right? Let's take Office 365. it means that beyond "end-user" services (like Word, Excel) there is some technical SSO service which are common to the platform. It can be viewed as lower (or technical) service layers, I think that what you speaker meant.
The SAML token is stored by you SP application inside your browser, either hidden inside web page, cookie or web storage. It depends on how your SP is implemented.
SAML response can be validate by each SP based on shared private key, so it will decrypt the token using this key and be able to grant user without the help of IdP redirection.
Tomcat have some extension to support SAML. But SAML is designed to work without being on the same instance, as the opposite as basic JSESSIONID cookies.
So you have several instances, of course.

Is there a standard for two Relying Parties with a common Identity Provider to share information?

Here's a situation that I have been considering recently:
A client has their own Identity Provider (i.e. ADFS)
My company's web application (Application A) supports SAML and OpenID Conect
Another company's application (Application B) also supporting SAML and OpenID Connect
Both Application A and B are associated with the Identity Provider
It is possible to ask the authors of Application B to change it
Application A and B have links between each other. In order to get from Application A to B, the workflow looks like this:
User is logged in to Application A
User clicks on a link to Application B
User is now at the Application B sign-in screen
E-mail address is entered
User is bounced to ADFS or similar system
User is now logged in to Application B and can see the resource
We would like to streamline the user experience:
User is logged in to application A
User clicks on a link to Application B
Application B somehow detects that the user is using SSO and redirects them to the appropriate page
User is bounced to ADFS or similar system. Hopefully if the last login wasn't too long ago, the user should be automatically authenticated.
User is now logged into Application B and can see the resource.
Right now, we're thinking that we rewrite our outbound links to Application B like so: https://example.com/redirect?email=user#example.com&url=/the-resource
This would allow Application B to detect if SSO was required, and I guess we'll do this if there's no other option. I would however like it if there was an already established standard for doing this, so we could just ask other companies to implement the same standard.
I know that detection of the SSO system is left up to the Relying Party, so perhaps this is just something that we have to work out with the authors of Application B.
Is there a standard for RP to RP data interchange where both RPs have a common Identity Provider?
If by "share information" you mean "Provide a hint as to the user's IDP" there is a standard being developed, https://ra21.org/ . Before RA21 started, i had a similar thought that i shared at IIW 22 (https://www.internetidentityworkshop.com/proceedings.html). It was essentially what you are proposing: put an IDP hint in the URL. The response was positive, but few folks had a use case where they could use it.
I note that the proposal (see Tuesday 5G, p 45 of the proceedings) the hint we discussed for OpenIDConnect would be the issuer ...redirect?issuer=[issuer]... See the notes for the specification justification.
If you are sharing a SAML IDP, you could take a look at http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-ui/v1.0/cs01/sstc-saml-metadata-ui-v1.0-cs01.pdf ยง2.2 Discovery Hinting Information . If your SAML IDPs included the child element in their metadata, that would be a straightforward way for the IDP to establish how RPs could hint to each other, and the value in the URL could be ...redirect?DomainHint=[whatever].... It's been some years and i can't remember
As a final note, sending the email address in the URL would violate so many privacy expectations. Do not put PII in your URL!
I'm afraid there is no standard for SAML relying parties/service providers to exchange information. All protocol messages are between the claims provider/identity provider and relying party/service provider.
In lieu of a standard, what you're proposing looks reasonable.
Sounds like you need a 'WAYF-less' URL entry point for Application B. WAYF = Where Are You From? and was the old way of finding out which IdP a user was associated with. If the user is already authenticated at Application A, then Application A knows the entityID of the IdP for that user. The user's IdP will also have an authentication session for them as they have already logged in to Application A.
So you could have in Application B:
https://applicationb.com/sso?entityID=https://some.idp.com/shibboleth
Application B then loads the SAML metadata for the entityID and automatically redirects the browser to the SSO URL associated with the entityID and the IdP will redirect the user back to Application B's SAML consumer endpoint. The user will not see another login screen (unless their IdP session has expired) and Application B will get its own set of SAML attributes.
Sharing attributes in the URL isn't ideal as Application A might be entitled to see the user's email (as released by the IdP) but Application B might not. So it's best to follow protocol and let the IdP release the attributes to Application B, separate from anything Application A knows about the user.
The only thing A is sharing with B is the entityID of the user's IdP. That allows B to begin the SAML flow and get the attributes for itself.
I think you're on the right track. It's entirely up to the RP whether it thinks it should use the IDP or not so you just need to pass enough context when you navigate to app B so it can make that decision. So in this case the "standard" would be front channel navigation to a known endpoint with the information you require in the query string or hash.

How does SAML solve SSO?

After reading a few articles on SAML, including "SAML for dummies," and the SAML wiki article, I'm still entirely unclear as to how SAML actually solves the SSO problem. Suppose I take something like a Google account as an example. My understanding is that if I go to GMail and SAML is implemented, I will be redirected to an IDP, which, let's say, is Google's sign-in authority. My browser then goes there with a redirect, and I'm asked to log in. After providing the correct login info, I return to GMail with a token and SAML response encrypted with Google Sign-in's private key, which is then authenticated using GMail's public key, thus verifying that I am, in fact, who I say I am.
What's confusing to me, is that this seems to solve the problem of signing in the first time, or into a single application, but I don't understand what happens when I now go to Google Drive. Even if my browser saves the SAML token/response as a cookie, I would have to sign in again after the token expires, which, I read, is something like 2 minutes later. Moreover, even within the same application, requests to separate resources or endpoints seem like they would time-out in the same fashion.
The only hint I have is that, according to the wiki article, step 1 has the target resource at the SP check for "a valid security context." However, if GMail and Drive are separate applications which aren't communicating with each other, how would Drive know that I already have a valid security context?
Questions:
After the initial authentication, what information needs to be sent with future requests to the same or different application/endpoint? For example, perhaps the SAML assertion saved and resent with every request.
How is this information secured/verified?
What timeouts are associated with SAML's SSO, and how are the timeouts enforced on both the SP and IDP sides?
What you are missing is that the Idp (Google's sign in page in your example) sets a session cookie on the first login. When you access Google drive as the second application, it has indeed no knowledge of the gmail session. Google drive does a redirect to the idp to get an authentication.
Now, the idp has an active session thanks to the cookie on the idp domain. That makes it possible for the idp to reply to google drive with a new assertion, generated from the persisted session information.
You're right that each assertion is normally only valid for a few minutes, but that isn't a problem as the idp can create a new assertion for each application.
For timeouts: The Idp can set a SessionNotOnOrAfter condition in the assertion to tell the SP that it must terminate the session at a given time.

How to support multiple user bases in SAML-based SSO without synchronizing them?

I am reading about SAML2.0 based federation as it is supposed to apply for SSO in the current setting:
In application A a user has credentials email/password1
In application B, the same user has credentials username/password2
If the user logs in at A, he/she should also be logged in at B
SAML v2.0 seems to be a good choice in this situation:
central identity provider (IdP), maybe A or B or a third party C.
A and B would be service providers (SP)
if user tries to access A, A would request SAML assertions from the IdP containing email
if user tries to access B, B would request SAML assertions from the IdP containing username
But if the user is authenticated in A, how should he/she be logged in B (for which username)?
Documents about SAML (e.g. here: https://www.oasis-open.org/committees/download.php/11785/sstc-saml-exec-overview-2.0-draft-06.pdf) pretend that SAML allows SSO without requiring to synchronize or migrate identities between all players.
However, I don't see, how all this should work without maintaining and merging all credentials of the same subject in the central IdP which in fact is a kind of synchronization.
If you have the impression that I am quite confused about SAML v2.0 capibilities, you are right ;-)
As a service provider, SAML doesn't allow you to do away with a user store usually. This is because it's a method by which you externalize authentication only. Most service providers have a 1-to-1 relationship of users in their store, to users at their identity providers. However, it may not need to be this way, as you can do a one-to-many federation as well. I'll expand shortly.
In the one-to-one, you will generally use either a "just in time" provisioning method, or an out of band user synchronization method. The just in time is usually done via attributes provided in the assertion, and is done by the SP when it realizes that the user that has been presented in the assertion doesn't exist the application's user store. The out of band method is some other process, a directory synchronization, etc. A user gets add to the IdP's store, and some process adds that user to the SP store, via flat file, XML, etc.
Having said that, depending on the type of service provider, you could do a one-to-many, and count solely on the attributes provided to support the needs of the application. Let's say you run a printing operation. You could agree on having the IdP send a cost center along with other attributes for the user (name, number, email, etc.). Then all the data is stored just on that print job, with the Cost Center sent back during billing. I will say, I've only seen a couple of instances of one-to-many federations in my career.
I don't think your example is quite right - meaning you didn't ask it quite right, but then again, you're not familiar enough, maybe.
Let's presume the following:
Service Provider X needs username
Service Provider Y needs email
Identity Provider A can provide all of these from their user store
The user shows up at SPX. SPX says "based on the url you went to (idpa.serviceproviderx.com), I know you need to be sent over to IdPA." and redirects the user to IdPA. IdPA authenticates the user, looks at its "attribute contract" to determine that it's supposed to send username to SPX, and redirects the user with that attribute as its "subject" in the assertion. SPX consumes that assertion, and can map the user back to where they are supposed to go.
Now, the user is browsing through their portal, and clicks a link that starts an SSO to SPY. The user is already authenticated to IdPA, so IdPA checks it's contract and sees it's supposed to use email with SPY. It creates an assertion for SPY with email as the subject, and redirects the user to SPY for consumption of the assertion and connection to the application.
Now, in both those instances, the IdP has to determine what to send to complete the contract with the SP - and it always will. This is based on a "contract" - some form of agreement between the IdP and SP that has to be supported by administrators of both systems.
Ok, I think the main missunderstanding here is how authentication works in SAML. I SAML the IDP authenticates the user. This means, you have no crederial store at the SP.
SSO in SAML happends at the IDP. If the user has already signed in once at the IDP the user is just sent back to the SP without authenticating.