How to prevent JA-SIG CAS spring security redirect loop? - spring

I'm using grails with spring security and the JA-SIG CAS spring security plugin.
One way I get this problem is when I have logged into the CAS server and I restart my application.
Another way is if I log into another application via the same CAS server and then when I access my application then spring reports me as being logged out. If I try and go to a secured page then the login controller sends the browser into the same redirect loop.
I can observer a stream of get requests to the cas server which is redirecting back to the application.
Basically the problem is that spring security isn't aware that I've already logged in to the CAS server, so bounces back to CAS server which says I'm logged in and bounces back to the app
I'm also using the single sign out. One workaround is to force a renew login when the application thinks someone is not logged in but it's not really a satisfactory solution.

Basically the problem is that spring security isn't aware that I've already logged in to the CAS server, so bounces back to CAS server which says I'm logged in and bounces back to the app
Check PreAuthentication docs. You'd have to implement a pre-auth-filter to let Spring know of an external authentication.

Related

Advice on Spring boot Server config

I‘m not new in either Spring boot or Spring Security but I am in Spring Authentication‘s Server.
Description
I have tree apps:
a spring boot backend,
a flutter frontend and
a Keycloak for authentification.
The Backend has only one login method, that is oauth2 and is client of Keycloak. The login method for the Backend is already implemented and is working, using Authorization code.
The flutter should also log into the Backend using Authorization code, but this part is not yet implemented.
The Backend is the part I‘m responsible of and the workflow should be following:
The user on Flutter tries to login
The Flutter App then requests login from Backend App
Backend App, as an authorization server with only one login method which is Keycloak, redirects the user to Keycloak.
The first authentification and authorization happens on Keycloak.
The Keycloak redirect the user on the Backend.
The Backend finds out who the user is and authorizes him.
The Backend redirect the user to Flutter‘s scheme and then flutter open (or continue).
The Flutter calls the Backend to get tokens.
Now my question is how should I configure the Backend, so that it behaves as Authorization‘s server?
This I what I‘ve tried.
I‘ve used the newly created spring-authorization-server. So my SecurityFilterChain already contains:
…
http
.oauth2Login(withDefaults())
…
Now my backend is resource server for itself and client of itself (I can‘t dissociate it now). So I‘m thinking of
adding .oauth2ResourceServer with the configuration of this same server for verifying the tokens I will issue, and
adding .oauth2Client with again the configurations pointing to this server, for the Flutter app being able to login.
Now I don‘t know how to turn my backend into Autorization server, and to be more precise, how to turn on authorization code for user login.
Thanks for reading. Any help would be appreciated.

Spring SSO always creates new session after refresh the client web app

I was creating my own oauth2 server with SSO enabled for Google and Facebook. I found this example https://github.com/spring-guides/tut-spring-boot-oauth2 to be very useful and I was able to make my oauth2 server expandable after several tweaks.
For session storage, I used redis and everything seems to be working with the spring magics.
However I encountered a session problem when implementing logout. According to single sign on best practice, when a user logout from one client, all other clients with the same session from the auth server should also be logged out. So I added an endpoint for each client to invoke upon successful login to register it's name based on the user session from the auth server. However I noticed that each time I refresh the page on my client web app, I get a new session from the auth server. As a result, each time when I try to logout, the session associated with all registered clients will always become the old one.
I've been searching for solutions online but no luck yet. It would be greatly appreciated if someone could help me with this issue.
TL;DR version:
I implemented an oauth2 server with SSO enabled for Facebook with Spring Boot. After I successfully logged in with my Facebook account, I can see my client web app resources. Every time I refresh the page, I see a new session gets created from the oauth2 server and it gets stored in the redis storage and all the old sessions are kept in the storage as well.
UPDATE
It seems that all the new sessions are generated by anonymous users each time I refresh the page.
Ok after some digging, it turns out that anonymous user by Spring Boot is not much different from unauthenticated users, according to this doc https://docs.spring.io/spring-security/site/docs/current/reference/html/anonymous.html.
It makes sense that every time I refresh page a new session would generate. My problem was that I wasn't using the correct session ID when registering client app upon successful user authentication. Therefore I override "SavedRequestAwareAuthenticationSuccessHandler.java" file so that I can obtain client_id from the request parameter and then register the correct session ID obtained from the Authentication object to this client ID.

Spring SAML SSO do not share session

I have configured WSO2 Identity Server as IDP and have two applications configured as SP. All working fine, except few things:
when I logged out from one application, another application don't see, that I was logged out
when I login into one application, another application don't see, that I was logged in
IMHO, there is main principles of SSO and SLO.
When I check SecurityContextHolder.getContext().getAuthentication() there is no changes after logout or login in another app.
Maybe I should call WSO2 page /samlsso before every load url?
What can I do wrong? How to retrieve from another app, that user logged out/logged in?
EDIT:
For example, WSO2 API Manager Store have such mechanism:
when I logged out from my application and reload Store page, then going redirection to main not logged page in Store. Same with login.
UPDATE:
I found problem in class org.springframework.security.saml.websso.SingleLogoutProfileImpl. When logout request is coming from WSO2 IS, than objects Authentication and SAMLCredential are nulls and error No user is logged in is occured, but for real user still logged in in Spring SAML application.
Same discussion was here, but with no effect :\
You have to verify whether both apps are calling Identity Server (IS) using the same host name. E.g. https://is.blahblah.com/samlsso.
IS session is based on cookies ('commonAuthId' and 'samlssoTokenId' cookies to be specific). If apps are calling IS using two different host names, there will be two different sessions created at the IS side. For SSO and SLO to happen both apps must share a single IS session.
We are using travelocity.com and avis.com web app for test SAML2 sso. You can found the more details here[1]. Further you can checked this documentation[2] Registering the two service providers in the Identity Server and followed the 1 to 8 steps.
[1] https://docs.wso2.com/display/IS500/Configuring+Single+Sign-On+with+SAML+2.0
[2] https://docs.wso2.com/display/IS500/Customizing+Login+Pages

Spring security, AJAX and SiteMinder

I am implementing Spring Security login and I am trying to understand something, here is the scenario I want to implement:
For initial login show login page and let user in.
If after some inactivity session expired and user makes some action show him popup window to authenticate (js-based popup in browser). Continue with the action like there was no login form.
Implementing form is easy, but how do I make the popup work - let's say I make the request to some protected URL after session expired, how do I make sure it's not forwarded to login page, but to my login handler that shows popup window?
Another issue - I need to integrate with SiteMinder, so I would need to read the Login/Password combination and after it's read, forward to SiteMinder for authentication, after that's done I want to return without forwarding.
Answer to SiteMinder issue:
Siteminder is generally installed on a Webserver behind your servlet container.
Also, Siteminder manages the authentication and an application does not have access to a user password at all.
To integrate with Siteminder use this filter:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e6295.
Answer to the login with the popup issue: since you need to integrate with Siteminder, I would not recommend to implement the login via the popup.
The sample given on the above springsource website is quite primitive and can break in several use cases. Using the SM_USER header alone has several caveats, see my answer here: How to validate SM_USER header in Spring Security preauthentication for siteminder
CA SSO aka SiteMinder, as well as other traditional html-form-request-response SSO systems, have a hard time dealing with Single Page Applications and protecting the web services that you invoke via AJAX, without breaking the flow of your application.

Adding CAS to Spring Webapp with GWT results in page not found, but logs in after refresh

I've tried to debug this without any success. I have a working Spring Application with GWT and Spring Security, but when I change the security-context around to use CAS authentication, I do get redirected to the cas page (usually), but after successful login, I get redirected to the correct url, but I get a "page not found error" at the browser level. After refreshing the page (same url), I'm logged in, and application loads as expected. No errors in the logs, as far as I can tell, no differences in what's happening in the application when using CAS vs normal spring security form login.
I believe this answered my question:
http://static.springsource.org/spring-security/site/faq/faq.html#faq-cached-secure-page
which basically states that if you're securing html pages, you're in charge of configuring caching, so that a cached page can't be accessed. In my case, this wasn't entirely clear, as the gwt services were still getting secured, so I wasn't seeing secured content, but still, that was the problem-

Resources