Global Logout using in Shibboleth by deleting IDP cookie - authentication

I have a product which authenticates using Shibboleth.
When a user initiates a logout on the website
The web server sends a logout request to the Shibboleth SP.
SP deletes the cookies post on getting the request.
However if the user goes back to the website the login page is not prompted
For the configuration shown below I am using Shibboleth Service Provider given here
https://www.testshib.org/install.html#SP. It is configured to use the testshib.org IdP details of which can be read here
I believe that the IdP is not deleting its session cookie and re-login the user on Step 3.
More on IdP Cookies:
This wiki-source states IdP uses two cookies _idp_authn_lc_key which is deleted after authentication. and the second is a session cookie '_idp_session' for which it states that :
Once a user has been authenticated they will have a long-lived session
with the IdP which is tracked by a cookie named _idp_session. This
cookie contains only information necessary for identifying the user's
IdP session. This cookie is created as "session" cookie and will be
removed when the browser chooses to remove such cookies (often when
the browser is closed).
My question is
What changes do I need to make on the SP to request the IdP to delete the same and effectively create a GLOBAL LOGOUT ?

For what it's worth, you're going to have a very hard time forcing the IdP to log the user off. The cookie approach is an implementation detail, and not all IdPs use it, and it could change. Some IdPs may offer a logout URL, but honestly, it's potentially something bad for users (can you imagine if you could figure out a way to constantly deauthorize a user from not just your site, but their sessions with any other SPs?). You really only have control of your own sessions on the service provider.
Why not force re-authentication when your user returns / comes back to your SP? If they haven't been authenticated recently to the IdP after a visit (that's a field you get back from the SAML exchange), just send them back to the IdP again and pass the forced-reauth flag.
If you're using the Shibboleth software, it's even built in:
https://wiki.cac.washington.edu/display/infra/Configure+a+Service+Provider+to+Force+Re-Authentication

Related

Does Cognito cache the federated ID data

I am integrating my client's organization authentication in to one of their web application via ADFS. I integrated the Cognito pool with ADFS and the authentication seem to happen fine. However, I have the following question:
When attempting the fresh login, the ADFS authentication server screen pops up. The user enters the credential and gets redirected to the designated redirect URI.
However, on subsequent attempts the user is not asked for any credentials even after I cleared all the token data from Local Storage. The cookie for the document are also cleared.
Although, this seems like a desired behaviour I would still like to know how it happens. Does Cognito cache some kind of ID data somewhere. I tried searching for something like this but didn't find any related article.
"Does Cognito cache some kind of ID data somewhere"?
No, ADFS does.
There is a client-side cookie and a server-side cookie.
Let's say the ADFS timeout is set to 8 hours.
So you log in the first time, and cookies are created on both sides.
Now on the client-side, the access token expires (assuming OIDC) and the client sends a refresh token. ADFS checks its cookie has not expired and then sends a new access token.
As long as the ADFS side has not expired, you get SSO.
Just for completeness, when you log out, ADFS clears its cookie. When the client-side receives the logout response, it clears its cookie.
Now you have to re-authenticate.

Authenticating multiple web applications through single authentication mechanism

How can I authenticate multiple applications with a single authentication mechanism?. These applications are having existing authentication within them, perhaps I need to authenticate these apps into my system which is isolated from others. Please suggest a better approach
When using OpenID Connect, the first application the user logs in to, will redirect the user's browser to the authorization server (AS). Since the user does not have a session between the browser and the AS, it will present the login screen. The user signs in and is redirected to the application (client) with an ID token and access token. The application will then establish a session between the browser and the application (typically a cookie)
When the user navigates to the second application, it will also redirect the user to the AS, but now the user already has a valid session between the browser and the AS, so the AS won't show the login screen (it may show the consent screen if the user has not consented to the requested scopes), and will issue an ID token and access token to the second application.
Now the user has a authenticated session with both applications with a single sign on (SSO).
If you use OAuth 2.0 with OIDC, you can authenticate your user once and verify the access token at each app the user visits. This is a typical single sign-on flow (SSO).

sp initiated saml sso authentication

I am working on SP initiated saml sso and it is completely new to me. I have gone through lots of articles and videos(wikipedia, centrify chalktalk, medium posts) but i am not able to understand some of the things:
Is the saml assertion the SAML token? if not, then how is it generated?
Suppose i have a saml based IdP and two saml enabled SP. Now in a purely post binding, when i login to one of the SP and then login to the second SP, How does the second SP log me in? To be more precise, how does the second SP know that the user is already logged into first SP? What is that parameter(s) that decides it? (can i get more low level explanation on this).
Does the IdP store data in cookie about the session or is there something else that i am missing out.
If there are any articles based on this please do post them.
Thank You.
Let me first answer your specific question points:
1) Is the saml assertion the SAML token? if not, then how is it
generated?
-This is all just terminology for the same thing. A SAML Assertion and a SAML Token are the same thing. There are 2 different SAML assertions/tokens that are important for you to focus on. The SAML Request and the SAML Response. The SAML Request is what is sent from the SP to the IDP in SP initiated SAML SSO. The SAML Response is what is sent from the IDP to the SP as the final part of SP initiated or during IDP initiated SAML SSO. SP initiated is when the user starts at the SP app, is redirected to the IDP for authentication, and then sent back to the SP app by the IDP. IDP inititated is when the user starts at the IDP, and goes right to the SP. A SAML Assertion is just XML that has been signed, converted to a string and base 64 encoded. they are redirected with the user from SP to IDP and back.
2) Suppose i have a saml based IdP and two saml enabled SP. Now in a
purely post binding, when i login to one of the SP and then login to
the second SP, How does the second SP log me in? To be more precise,
how does the second SP know that the user is already logged into first
SP? What is that parameter(s) that decides it? (can i get more low
level explanation on this). Does the IdP store data in cookie about
the session or is there something else that i am missing out.
-This is specific to your IDP. As a Centrify SME, I can tell you how Centrify and similar IDPs work. When a user signs into the IDP, whether its from an SP initiated redirect, IWA on their corporate machine, or directly to the IDP itself, a cookie is added to the browser. In the case of Centrify, this cookie is called .ASPXAUTH. Every time a user is taken to the IDP after logging in, they are not prompted to log in again. So if a user starts at SP1, gets redirected to the IDP, logs in, and is redirected back, the cookie has been set by the IDP. Now if they go to SP2, by default that SP would also redirect to the IDP, but the IDP would not prompt for auth again because of the set cookie. So the user wouldn't notice the redirect and the IDP would just send them right back to SP2 with the appropriate SMAL response. So Like this:
SP1 > SAML Request and redirect to IDP > Log in to IDP and cookie is set> SAML Response and redirect back to SP1 > Navigate to SP 2 > SAML Request and redirect to IDP > Cookie is set so immediately redirect back to SP with SAML Response.
Centrify also has API's that can be used by SP's. For example, an SP could do a client side API call to /security/whoami to see if there is a valid ASPXAUTH cookie in place. So SP2 could check for a valid cookie and decide to to redirect at all because the cookie has already been set. https://developer.centrify.com/reference-link/securitywhoami
Hopefully this helps. I wrote a very basic example of this in c# while at Centrify. You can find the code here https://github.com/centrify/CentrifySAMLSDK_CS. Feel free to reach out here with more questions or find me on twitter https://twitter.com/NickCGamb
Yes, the Assertion is normally a fully portable token by itself, but there are ways to bind it to for example keys on the requester.
The second SP does now that the user is already signed in. The SP will redirect the user to the IDP with an authentication request to the IDP. IDP usually saves a cookie for the user when it authenticated the first time, this is not specified by SAML but generally how its done. When the user arrives at the IDP the IDP looks at the cookie and if the user authentication is still valid the IDP automatically sends a valid Assertion/token to the SP. It is possible for the SP to overide this behaviour by specifying the ForceAuthn attribute in the authentication request.
As for resources I would recommend the SAML Technical Overview from OASIS http://www.oasis-open.org/committees/download.php/27819/sstc-saml-tech-overview-2.0-cd-02.pdf

How do I keep the user logged-in with Implicit flow?

From what I understand, the end-result of the implicit flow is the access token, which allows the client (in my case a JS SPA) to authenticate into resource servers (APIs).
The access token is usually only valid for ~1 hour, then it expires - making it useless.
What should my JS app do then? Redirecting the user back to the auth server is unrealistic since then the user will have to reenter their credentials every 1 hour!
I also know that the implicit flow doesn't support refresh tokens so I can't use those either.
Is there a way to persist the user's login? How do things like Facebook keep you logged-in indefinitely?
Just to clarify, you are asking about the Implicit flow which is detailed in the OAuth 2.0 RFC rather than OpenID Connect which deals more with authentication of a user?
With the implicit flow you do have to regularly call the authorisation endpoint to obtain a new token, but if the user remains logged into their identity provider then they should not be prompted to resubmit their credentials, and the token will be returned as a hash fragment in the redirect uri, with no user interaction required.
You can use an AJAX call to get the token on a back-channel so your SPA app user experience is not affected by the need to get new tokens.
To address the points you highlight in your question:
The access token is usually only valid for ~1 hour, then it expires -
making it useless.
Correct!
then the user will have to reenter their credentials every 1 hour!
Not necessarily.
If the user stays logged into the identity provider (e.g. facebook, google) then there will be a browser cookie between the user and that provider. This effectively means the identity provider does not need the user to re-enter credentials. The authorisation server should be able to return you a token with no interaction required.
Is there a way to persist the user's login?
You can't control it from your SPA. It's totally dependent on the user staying logged onto the identity provider. If they stay logged into facebook, google (or whatever IDP you app uses) then you should be able to get tokens non-interactively.
This article nicely explains how the implicit flow can be implemented.
If the session at the OP is still active (via a cookie perhaps), then OpenID Connect has a mechanism to refresh tokens in a (hidden) iframe: prompt=none.
According to the spec, when sending this flow...
The Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an End-User is not already authenticated or the Client does not have pre-configured consent for the requested Claims or does not fulfill other conditions for processing the request. The error code will typically be login_required, interaction_required, or another code defined in Section 3.1.2.6. This can be used as a method to check for existing authentication and/or consent.
prompt=none is also referred to from the Session Management specification.

How does SSO (Single Sign On) work

I'm trying to wrap my head around SSO. It's my understanding that SSO allows you to login once and get access to multiple apps (if you have rights). So, I log into App A. I establish a token. How does that token become available to App B so I do not have to login to App B again (assuming user has rights to A and B)? My Apps are AngularJs apps. I access .Net WebAPis for data.
I can see if I login to App A and retrieve a token then launch App B from App A by passing the token to App B. This way App B has the token and can send to server to make sure user has access to B. However, if user opens a browser directly and goes to App B, then how does their session get established with existing token?
If the answer is there's session state on the back-end server, then how does session state match the user logged in App A with the new request for App B?
Thanks.
Well, there are certainly many ways to achieve it, and it can be tricky. I can give you one solution as an example:
Consider two apps on different subdomains:
The Fine Corinthian Turkey Shop (turkey.example.com)
Rent a Baboon (monkey.example.com)
These two web apps want to share signon, and arrange for a third hosted website for their single sign-on:
sso.example.com
Then the flow is:
Frank visits http://turkey.example.com/orders/12
Turkey redirects to https://sso.example.com/login
SSO presents user with login form, validates and issues token
The token is saved in a cookie on SSO.
User is now validated on SSO, but needs to get the token back to turkey.
SSO stores a combination of (Guid, Token, Expiry) on the server, where Guid is a random guid and Expiry is something like 30 seconds.
SSO sets a secure cookie on *.example.com containing the Guid
SSO redirects back to http://turkey.example.com/orders/12
Turkey can now retrieve the ticket from the cookie
Turkey calls SSO server and exchanges the ticket for the token.
Turkey stores token in the browser (typically a cookie)
Now let's imagine that Frank wants some nice juicy baboons to go with that turkey:
Frank visits: http://monkey.example.com/order-in-bulk
Monkey sees that Frank has no stored token and redirects to https://sso.example.com/login
SSO sees that Frank is already logged in as he has a stored token.
SSO stores a new (Guid, token, expiry) triple on the server
Process is identical to the initial login the rest of the way
However, if user opens a browser directly and goes to App B, then how
does their session get established with existing token?
If the answer is there's session state on the back-end server, then
how does session state match the user logged in App A with the new
request for App B?
I would say it's more about cookies and redirects than it is tokens. Tokens are generated once a user's identity is established.
So when you hit App B via your browser, App B redirects your user-agent to the Auth Server (which may in turn redirect you to a SSO site).
The thing to note is that the SSO login request is actually an HTTP request between your browser and the SSO server.
So the SSO cookie is already there - because earlier, App A would have also redirected your user-agent to the Auth / SSO server where the login was performed. The SSO server could then persist a cookie between you and it.
I can see if I login to App A and retrieve a token then launch App B
from App A by passing the token to App B.
I'm not sure I understand about App A passing its token to App B. Usually Apps (Oauth 2.0 clients) would not share tokens. App B should make its own request to the Auth server which (if the user is signed in) may skip the login part but would then need to verify that :
App B has rights to the scopes requested and that
the signed-in user has granted access to those scopes.
If the user is logged in and has previously approved scope access then all this processing is seamless to the end user other than a bunch of redirects.
This assuming you use the Implicit grant flow (I noted that one of your apps is an angularjs app).
If you use the code, password or client-credentials Oauth2.0 grants then you may receive a refresh token after initial user login and consent.
The refresh token equates to long-term access (for that app only) without the need again for login and consent from the end-user more than once.
sso.example.com stores a cookie and the same cookie help when Frank goes to monkey.example.com. If sso.example.com feels that cookie is too old then it can ask for login auth again.