How does IdP identify if the user has a security context - saml-2.0

I have a basic question regarding SAML2. Typical flow is that user requests a resource from SP that is protected. SP checks if the user has a security context (say cookie ?), if it does not find a security context, it constructs the AuthRequest and then redirects the browser to the IdP. Now IdP likewise first checks if the user has an existing security context. How does the IdP do this? Does the IdP also use a cookie for this purpose?

Yes. For SAML Web SSO Profile the session is almost always kept as a cookie in the browser at the IDP and SP. However, there are no rules on how to manage this. The IDP could choose to not keep an active session and prompt the user to login for each SSO transaction.
Ian

#Ian - Great Answer. However if the IDP does not maintain a session cookie [B/W Browser and Identity Provider (IDP)] than you miss out on a significant benefit of single sign on (SSO). The SSO User Experience (UX) feature that would be lost is described in the following scenario:
0) Assume IDP is registered with Google Apps and Salesforce.
1) Open Browser. NOTE: SAML is browser based. You need a browser for SAML to work.
2) Try to go to Google Apps; (you have no existing session cookie [B/W Browser and Google Apps]) who then Re-directs you to the IDP.
3) You sign on with your valid IDP credentials.
4) the IDP then stores a session cookie [B/W Browser and IDP] in your browser. (This is the step that #Ian mentioned can be skipped by the IDP)
5) The IDP then redirects you back to Google Apps (via HTTP POST) with SAML token embedded in the POST. You are now in Google Apps. (Now you have a session cookie [B/W Browser and Google Apps] stored on your browser)
5) Try to go to Salesforce.
6) Salesforce sees you have no active session cookie[B/W Browser and Salesforce], so they redirect you to the IDP.
* here is my point of added User Experience (UX) *
7) The IDP will look for a session cookie [B/W Browser and IDP], if the IDP is configured to not store maintain one you have to enter your Single Sign On (SSO) aka IDP Credentials AGAIN.
Discussion on Step7: Entering the SSO credentials for each separate service an extra-step times the number of services you are using. I think the main draw of the implementation is to enter credentials only once and get access to everything (the topic of security aside). However if the IDP does not store a session cookie [B/W Browser and IDP] you are still only using one set of credentials (instead of separate credentials for each service), so life is still easier.
#Ajava - You seem to be confused as to how cookies are used. I hope you can follow my steps above and get better idea of how cookies are used with SAML.
Here is also a good link i found that explains cookies: http://lifehacker.com/5461114/fact-and-fiction-the-truth-about-browser-cookies

Related

Why does Azure AD (or other OIDC Idp) require to enter user credentials for sign-in after sign-out?

I develop an authentication by extrenal idps in the my application. For while I support two idps using OpenId Connect protocol: Azure AD and Okta. My login page has widget for entering user's credentials (for built-in users and for domain users imported from Active Directory) and two buttons: "Login with Microsoft" and "Login with Okta".
First time user is redirected to login page and he attempts to sign in by Okta (or Azure AD). If he has already signed in Okta (or Azure AD) before attempt he will be signed in my app autmatically without entring his credentials (SSO in action). But if he signed out from my app, the next time he will try to sign in by Okta he will be redirected to Okta consent page and required to enter his credentials.
Why do second and next attempts require user's credentials but not lead to automatic sign in?
Is this SSO concept?
I develop on Asp.net MVC and use OWIN (Katana).
Thanks!
A likely reason the user is signed out of the identity provider is that your code is intentionally doing that when you call SignOut.
For example, if you are calling:
HttpContext.GetOwinContext().Authentication.SignOut(AuthTypes.Okta, AuthTypes.Cookies);
You are explicitly saying that you want to trigger sign-out for AuthTypes.Cookies (which probably clears your app's own session cookies) and AuthTypes.Okta (which probably includes redirecting to Okta to end the session and clear cookies over there as well).
If you only want to end the session with your app (but not necessarily end the user's session with the identity provider), when you call SignOut, you should only indicate your app's authentication types:
HttpContext.GetOwinContext().Authentication.SignOut(AuthTypes.Cookies);
After this, when the user accesses the app again, the app will not consider the user signed in (because when the user's browser accesses the app, it will not be presenting any session cookies). However, if the user were to be sent off to Okta or Azure AD again, the identity provider's own session cookies for that user will still be there, and they will be able to SSO with no extra prompts.
Note: I'm making a few assumptions about how AuthTypes.Okta and AuthTypes.Cookies are configured, since that wasn't included in the question.

How to use an Azure AD SSO access token to sign in on another website on a new browser

I have set up an AAD SSO enabled website A that gets an access token once the user logs in. Now, the user has the option to navigate to website B, but on a new browser that doesn't have access to the session of the browser that website A was opened.
Is there a way for website B (.NET MVC Azure hosted Web App) to be setup to accept the access token (for example: through headers) to authenticate the user and establish a newly AAD SSO logged in user on the new browser? (Users can't re-enter their credentials)
In my opinion, access tokens enable clients to securely call protected APIs, so it should be stored in backend. More often we use refresh token and access token at the same time to prevent the access token expiring.
On the other hand, if I have entered the credentials in one browser, then the identity platform knew the request came from me because some information would stored in my cookie of the website, but if I used another browser to visit IDP, it was impossible to let IDP know the request came from me, because I can't share cookie infomation with different browsers.
I find 2 videos on introducing SSO, I think they will help, here is the link.
Hope it will do some help.

SAML Response authentication

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.
Application has a link to different application. The Second application needs to validate the user credentials with the same IdP.
User clicks on that link and browser opens the second application. Browser contains the same SAML response from SP.
In Step 5 how can I authenticate the user with SAML response and allow the user to be logged in automatically.
Do I need another SP?
I will not be able to use the SP from step 1 as it is external application.
Appreciate your help
If the second application is in a different administrative domain, it should be done through its own SAML SP starting another SAML request/response exchange with the IDP. If it is in the same domain you may be able to pass an intra-domain credential such as a cookie between the first application and the second (or rely on full SAML as well). You would never reuse the same SAML response because that is meant to be one-time use only.

Get logged in user information in SAML Single Sign On google app engine

I am trying to get the user who is logged in via. SAML Single Sign On.
I have already implemented SAML Single Sign On and it works.
The code I use for programmatic login is :
apps = gdata.apps.service.AppsService(email=username, domain=domain, password=password)
apps.ProgrammaticLogin()
logging.info("current user %s", users.get_current_user())
//Redirect to a Google mail page.
But users.get_current_user() returns None always even though correct username and password is provided. I have crosschecked it by redirecting the page to Google Mail page and it successfully redirects.
I have googled this issue for hours now nothing goes the right way.
Can anyone please guide me what I am doing wrong ?
There are three different things going on here, I just want to make sure are clear for my suggested answer to make sense:
Google App Engine users service: You, as the developer, delegate authentication and authorization responsibility to Google Accounts (or the selected OpenID provider). Google will act as the Identity Provider and you'll act as the Service Provider.
SAML single sign on: Google delegates to you the authentication and authorization responsibility, you'll act as the Identity Provider and Google will act as the Service Provider. You'll be using SAML SSO every time you try to login any Google service using you Google Apps account, that includes Google App Engine applications using the users service.
ClientLogin: It is one of the methods for authenticating to use a Google API by giving username and password. It's deprecated, it's hard to maintain and insecure since you are hard coding the credentials and the app could have access to everything. I'd recommend switching to OAuth instead. In the first two lines of code You are initializing the Google Apps provisioning API with gdata.apps.service.AppsService, if you are not going to retrieve or create users/groups/alias is useless to do that. If you are I'd also recommend switching to the Directory API part of the new AdminSDK
For your particular case I'd suggest checking if there is a current user logged in, if not redirect to the login URL using the GAE users service.
user = users.get_current_user()
if user:
logging.info("current user %s", user.email())
else:
return redirect(users.create_login_url(request.url))
In case you always require that the user is logged in you better set the handler as login: required
The user will be redirected to the SAML SSO page to log in to his Google Account in order to access the GAE app.

SAML indendity propagation

In my scenario I have the following architecture elements:
- SAML secured Portal (Domain A)
- User
- SAML secured API( Domain B, so different domain than the portal)
- an IdP
The user will login first to the portal, when not authenticated, the portal will redirect him to the identity provider to login. Once logged in to the IdP and hence to the Portal, the Portal will possess a SAML token identifying the user.
Now this portal will need to automatically call the API (present on another domain), and pass to it a SAML token identifying the user. Problem is that the portal only posses the token that has been provided to him, and hence my question:
How can I propagate the identity of the user through the invocation chain?
For instance, is it possible to share same token between different relying parties? If yes, what are the constraints that the issued token should respect to make sure it can be "shared" by different entities?
Many thanks in advance!
One way could be that the portal rather than calling the API directly, instead should redirect the user to the API.
This way the API will find the user doesn't have a valid session, will redirect to the IdP where the user is already authenticated. The IdP will then redirect back to the API with the SAML response for the API.
This will all be transparent to the user, who will just see the result from the API.

Resources