SAML2 support is the new addition to Spring Security library.
According to this:
https://github.com/spring-projects/spring-security/blob/master/docs/manual/src/docs/asciidoc/_includes/servlet/saml2/saml2-login.adoc
Saml 2 Login - Not Yet Supported
1. Mappings assertion conditions and attributes to session features (timeout, tracking, etc)
2. Single logout
3. Dynamic metadata generation
4. Receiving and validating standalone assertion (not wrapped in a response object)
it doesn't support single logout in the current version, which is essential for cases with multiple identity providers.
What would be the right workaround to enable single logout for multiple IDPs?
The single logout feature that Spring Security would provide would be to log out many SPs against one IdP, not multiple.
The typical flow for a user is to log in to some IdP and then be redirected to one or many SPs over the course of their session. When they click logout, it's to end the session they originally established with that IdP.
The way that this would be addressed in Spring Security is via a LogoutSuccessHandler. LogoutSuccessHandlers are invoked after the SP has successfully terminated their session (clicked the logout button). You can imagine a LogoutSuccessHandler that would either redirect to the IDP's SLO endpoint or hit a backend IDP logout endpoint.
It's not very common for an SP to try and merge a session initiated by a user logging into one IdP with one from that same user logging into another IdP, which is the use case I think you are describing. But feel free to add more detail if you feel like I'm missing something.
Related
I am using Spring Boot - 2.6.6 and Spring Security - 5.7.0-M2 with the spring-security-saml2-service-provider library to create a SAML service provider application. I followed Spring's sample project Spring Security SAML2 Sample so my setup looks very similar.
I want to turn off the generated Login and Logout pages located on /login and /logout. The login page shows a link to each IDP configured and the logout page has a button that initiates the POST logout flow.
They appear to be created by Springs internal code - Saml2LoginConfigurer.initDefaultLoginFilter when Saml2LoginConfigurer.loginPage is not set or the DefaultLoginPageGeneratingFilter is active. Setting the loginPage variable only changes where the login page is displayed and breaks the metadata configuration from my Identity Provider: it does not turn the login page off. I had no success trying to turn off the DefaultLoginPageGeneratingFilter.
How could I do this?
The sample already includes everything needed to automatically redirect to the IDP (Okta in this case) and get redirected back. So the login and logout pages are only accessible if the URL is changed. Having said that, I can see why they are undesirable if they aren't being used.
To disable them, the simplest way is to provide an AuthenticationEntryPoint. This disables the filters that generate the login and logout pages. For example:
http.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/saml2/authenticate/two"))
)
The reason this works is that it does explicitly what happens behind the scenes in Sample2LoginConfigurer.init while also disabling what happens in Saml2LoginConfigurer.initDefaultLoginFilter.
I have a requirement where I need to develop a Login flow for an Enterprise application that is a Spring MVC application integrated with Spring Security.
The requirement is I should be restricting the user to one session:
Example: I have users two groups A and B.
CASE A: (WHEN THERE ARE NO SESSIONS)
Users from group 'A' have a specific role, but when they log in and when they don't have a previous session, they should be given two options to select from as their existing role (or) another role (SPECIAL ROLE) that I should be updating in the application on the fly.
Users from group 'B' just log in and get to the dashboard without any choices.
CASE B: (WHEN THERE IS ALREADY AN ACTIVE SESSION)
Both the users from the two groups should get an options form to choose from if they want to log out the previous session and log in here (OR) just go back to the user login page. When they select log out and log in here other session would be terminated (invalidated).
If they choose to go back to login page previous session is not affected.
CASE C: (WHEN THERE IS ALREADY AN ACTIVE SESSION FOR A USER FROM GROUP 'A' WHO CHOSE THE SPECIAL ROLE)
When any user from Group 'A' is logging in should get a choice to log out the other user session and log in here with the SPECIAL ROLE or just log in as with his actual role.
I am trying to develop this requirement with Spring security but when I configure session management the framework just logs out the other user and invalidates the old session. I should be giving custom implementation to ConcurrentSessionFilter or may be at some other filter level (I am confused) where I can show the choices to the user and do the things.
AND
also when I use custom Concurrent Strategy classes the sessionRegistry.getAllPrincipals() is giving me an empty list but when I configure the Spring security sessionManagement().sessionRegistry(new SessionRegistryImpl()); I am able to get the populated principals.
I also tried custom success handler and tried to redirect based on his roles it works fine but it doesn't complete my requirement and I am sure that I should be doing some custom implementation to a specific Spring Security filter chain to implement it but I am just getting lost after days of reading and lack of resources on session management using Spring Security.
I am stuck here, any help would be appreciated. This is the first time I am working with Spring Security and implementing session management.
Thanks in Advance :)
using Spring Security, MVC, Core 4 Java config
I have two projects - one for Java Spring Services and other for Web UI.
I have the login functionality ready and as my views are in "html" extension kept in completely different folder
How do I check the session/authentication of the user securely while navigating the HTML pages and make the user return to the login page in case the session expires or no success session at all?
The approach I do not want to follow :
I do not want to cluster my URL with session id's unless there is no better way
I do not want to use Spring Security and my views are designed in
HTML and AngularJS.
Cookies again is not a secure way to do as anyone can get all the
cookies from frontend.
You need, in Spring side, to setup an HandlerInterceptorAdapter which checks the login status and return an error code to the html side.
The Spring handlerInterceptorAdapter can be configured to intercept all of your controllers hand has a preHeandle method which can be used for checking user session or for login the user if your application is sessionless.
Then all of your WS will get no data.
Docs here
https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-handlermapping-interceptor
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.html
If you want protect pages too you get to do some work on angular side in order to avoid the visualization if the pages WS return a proper error code (user not authorized). Or you can check for a token or a coockie.
Or otherwise you've to put your templates and their access under Spring Control
in a way that your interceptor will run before serving them.
You need to send a cookie with some required tokens, after successful user authentication.Then create a service like /userAuth, browser will automatically append your cookie(what ever sessionID, tokens,etc..) info to your http request headers.Based on the request header data you need to validate the user access or authorization.
if user is not authorized send 401 as status and on you angular $http failure method you need to emit/broadcast a logout event to redirect to appropriate page.
In my web application, there are times when an authenticated admin might want to impersonate another valid user of a system without having to know that user's password.
How can I use Spring Security to give admin users the ability to impersonate normal (non-admin) users of the system?
The Spring Security documentation is silent on this and I can't find anything anywhere. Surely someone must have solved this.
Thanks!
It's in the Spring Security 3 and Spring Security 4 docs aptly named, "Run-As Authentication Replacement."
The AbstractSecurityInterceptor is able to temporarily replace the Authentication object in the SecurityContext and SecurityContextHolder during the secure object callback phase.
I believe the recommended way to do this in Spring Security is with the Domain Access Control lists, see GrantedAuthoritySid #
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/domain-acls.html
However, impersonating another user is more than just having a "delegate identity", you should also consider the implications on logging:
Do you want your logging to appear as Original User or Impersonated User (or both?)
Do you want the "impersonation" to show only what the impersonated user sees, or the superset of permissions of the Original User and Impersonated User?
Yet another possibility is to create a "log in as" feature, which essentially changes the principal identity of the current session - or starts a new session with the impersonated identity.
In all of the above, you may inadvertantly open up a security issue - so I think this is why impersonate-style features are not that common place. Rather, designs trend towards Role Based Access Control (RBAC) or Attribute Based Access Control (ABAC). Using RBAC / ABAC, you could create a delegate style feature where you create delegate attributes/roles - and in the special cases where you need to show the source/target of the delegation (e.g. for audit logs), you handle those as corner cases.
If you want an admin user to be able to impersonate another user (eg for QA/Testing purposes), have a look at the SwitchUserFilter
A decent example of the XML config you need is provided here
I have some confusion with how spring security works:
In my application, I need to have a login page for users after which they are redirected back the page from where they came. I went through a few spring security tutorials and read some articles, and the examples work by securing a certain page on a site (managed by the <intercept url ..> tag). Then Spring security will generate a login page (or you can specify your own) in order to access the secured page.
I am confused because I don't want to necessary secure a given page on my site: I want a login page for users to log into after which they have access to elevated features of the site (through spring security's authorization features). My question is: given what I described, what would be the strategy to create this login page which, after login, would grant the logged in user the appropriate authorities?
The hack I thought of would be to create a simple JSP page who's only function is to redirect back to the previous page. Then I would use Spring Security to secure that JSP page. But it seems like there should be a better way of doing this...
Thanks
When the user is not logged in yet, you could treat him as ANONYMOUS. So the page will hide everything marked with <sec:authorize ifAllGranted="ROLE_SUPERVISOR">.
See Anonymous Authentication for more details.
I dont know if you still need an answer since your question was in feb., but once the user has logged in via SS, you can get the SS Authentication object in your controller as:
SecurityContextHolder.getContext().getAuthentication();
What I do is I create my own Authentication class and wrap it around Spring's Authentication class so if I ever change providers I just extend my Authentication class with a new provider. Then I put my wrapper in the session so I can query the authentication object via OGNL anytime I want to know if someone is logged in and what the details are.
ie:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth.isAuthenticated()) {
session.put("authentication", auth);
}
to logoff, simply invalidate the session
session.invalidate();
I also do kind of a trick with SS. Since SS automatically provides the form login when accessing a secured realm (same workflow as j_security_check), you can define the login to point to a page that doesn't exist in the secured realm:
click here to sign in
SS will then fire up the login page. Then whatever framework you are using, you can intercept after the login to get the Authentication object.
Hope this helps.
You have to set the always-use-default-target="false" so that spring security will redirect automatically to the previous page, if it is set to true, it will always take to default home page. The property is on form-login tag.