CAS workflow in case of Single Sign On (SSO) for Spring - authentication

I am wondering how CAS works (workflow needed). Imagine:
User authenticate with CAS on App1 (example.com/app1, for example).
User goes to another application (example.com/app2).
Every application must show user's name on top of the page. How they know it? In case of just ONE application, the workflow is pretty clear:
App1: While user browse pages without authentication, just show "Login" link as user name.
App1: At one moment user presses Login.
App1: Redirects user to CAS
CAS: Requests user's login/pass
CAS: User enters login/pass
CAS: Redirects user back to App1
App1: gets token and user name (or ID) from CAS, and gives some rights to this user.
Done.
But now: how the App2 (App3 and so on) knows that user is already authenticated? Do they all have to redirect user from EVERY page to CAS just only to know, if the user already authenticated and request his name?
In case of Spring it will be a huge redirections, while I have some independent applications like:
example.com/App1
example.com/App2
...
example.com/AppN

I don't have have 10 reputation yet, so you will need to check the workflow image at
http://idms.rutgers.edu/cas/how_does_it_work.shtml
When a new user initially logs into an application they won't have established a session with the application. Instead of displaying a login form asking for the username and password, the application (via the CAS Client) will redirect the browser to the CAS login page.
CAS then authenticates the user. If the authentication fails, the CAS login page is displayed again with an error message. So until authentication succeeds, the user will not be returned to the application. If the user is not sure how to proceed at that point, there are help desk links on the CAS login page. Once the user authenticates successfully, CAS will redirect the browser back to your application. CAS knows where to redirect to via a {service} parameter that you append to the CAS login url.
When CAS redirects the authenticated user back to your application, it will append a {ticket} parameter to your url.
The ticket returned to your application is opaque, meaning that it includes no useful information to anyone other than the CAS Server. The only thing that your application can do is send this ticket back to CAS for validation.
CAS will then either respond that this ticket does not represent a valid user for this service, or will acknowledge that this ticket proves authentication. In the later case, CAS will also supply the username so that you know the identity of the user.
The application must provide its own session management. Once the user is authenticated, your application should keep track of this fact within a session so that you don't have to reauthenticate them with the CAS Server. Typically this would be the same as if you authenticated the user directly from your application.
Each application should provide their own logout facility which will invalidate the session and require the user to re-authenticate into the application. Note that if they are using SSO through the myRutgers portal, they will not have to re-enter their username and password.

Using CAS means, that the CAS-Server keeps track of which user is authenticated globally (using a cookie which stores a Ticket Granting Ticket Id - TGT). Each application must maintain its own mechanism to key track of a principal session and the corresponding information.
So if a user wants to access a secured application APP1 (and is not authenticated), he will be redirected to the CAS-Server. Without sending a valid TGT the login-form is presented, otherwise (or after successfully authenticating to the CAS-Server) a Service Ticket (ST) is generated, which must be presented to APP1. Here this Service Ticket is validated against the CAS-Server (using server-to-server communication) - if valid, the userId (and perhaps additional information) is returned.
Now it's up to the application APP1 to create a principal based on the userId and to provide authorization information (e.g. the CAS-Server authenticates against an LDAP, whereas APP1 stores the user data in a database).
All subsequent requests to APP1 should not involve the CAS-Server anymore.
If the user makes a request to APP2, the mentioned process restarts again.

L'sync,
Have you tried posting your question to the cas-users [cas-user#lists.jasig.org] mailing list?
I have been working with CAS for the last 6 months and from what I understand, App2 (App3 and so on), without redirection to CAS do not have a way of knowing the user-attributes.
You can avoid putting all pages of App2 behind the CAS filter by either storing the user-attributes along with your web-session and/or by embedding an iframe-header in your pages which displays the login-name.
Marvin who is a CAS contributor maintains an excellent CAS client test webapp on GitHub where you can see how he reads the user-attributes.
https://github.com/serac/java-cas-client-test

Related

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).

Thinktecture Identity Server password reset redirect

In my environment I have presently two applications, lets call them portal and sso. Portal is where I manage user accounts and allow people to register. SSO is my implementation of IdentityServer. I want to require users to reset their password after 90 days or after they had their password recovered for them. I can check for this in the AuthenticateLocalAsync function, but the question is how do I redirect them to the portal password reset page? Or is it easier to add a custom page to the IdentityServer to handle password resets of this nature? Are there any examples of this, specifically where the identityserver is not embedded into the application using its login functionality?
Your best option is to create a "reset password" page in the same IdentityServer project, and issue a partial login redirecting to that page every time an user with expired password completes the sign on process successfully.
With this approach you can catch users with expired password before they are effectively logged in, without completely breaking the login flow.
You can find some details in the IdentityServer3 CustomUserService sample, specifically in the "EULA" sample which uses "EulaAtLoginUserService".
I do not think there is a way to directly redirect the user to an external endpoint (e.g. your Portal residing in another domain) during the IdentityServer login flow.

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.

How does SE's single signon work?

Basically I just want to know how does StackExchange's single signon system work?
In the SE network you need to login only once in one of the websites to be automatically logged in to the other sites upon visiting.
How should I implement such a feature in my own network of sites?
I assume it uses the cookie which resides on the user's browser and then authenticates it with the originating site. If it is legit then it logs the user in automatically.
You have to implement SAML or oauth2 to allow sso on your network.
In case of SAML your child websites will be service providers or resource servers.
While you need to setup and identity provider.
The sequence of events will be like this.
1. User hits a url of songs website, this site is resource server and does not handle authentication.
2.To authenticate resource server will construct a SAML authrequest and redirects to identity provider after signing it.
Idp verifies the signature after receiving authrequest.
3. User will be presented with a login form, user has to end login credentials.
4. After user authentication idp will generate a SAMl token and redirect back to resource server.
5. Resource server will extract identity information from SAML token, resource server will login the user with session or cookie.
Depends upon which technology you are working in i have implemented it in php using simplesamlphp.

Global Logout using in Shibboleth by deleting IDP cookie

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