Remember-me functionality for Spring Security - spring-security

Here is the issue:
We have to implement two-step login process. First step - user enters name/password and is being authenticated. Second step - user may be presented with secondary select screen where he chooses an option via simple click. When this is done user is finally authorized for certain set of actions. This concludes authentication/authorization process for current user session.
We do use Spring Security in its standard form: first login screen is handled by default Spring Security stack and as soon as user is in - Spring considers the login process done.
The secondary selection screen is completely outside of Spring Security and all we do upon user selection is set the properly configured object back into security context. This works for current session as expected.
We do have remember-me functionality as well which is implemented via checkbox named _spring_security_remember_me in the first login screen and also an overridden UserDetailsService bean.
The remember-me works fine for as long as there is no secondary select screen option. Since the secondary screen has nothing to do with Spring Security, the remember-me mechanism would not be activated for secondary option and all it is capable of is to remember only the first login step. This results with having to ask remembered user the option and we are tasked to avoid this.
Having both login form and secondary selection on the same page is not an option.
We could use additional cookie if the secondary selection is required and based on that cookie "silently" pass the needed parameter when authenticating. But this would mean that we have to do bunch of manual stuff which Spring Security "ought" to offer, also this puts some security logic and tokens outside of Spring managed security and remember-me functionality.
So here is the question to security gurus: how to "force" remember-me functionality to accept the secondary presented option? If it was possible for Remember-Me filter to "inspect" the passed URL and identify that remember-me option is chosen, we could add this parameter. But this does not sound like it is possible.
Is it possible/feasible to use yet another login form on secondary screen and "silently" pass just needed additional parameters? I know we won't include the user name/password in this case, at least not in clear form. The option sounds like it can be done, but I am still believing that there might be an easier way to just force the Remember-Me to do what it does. Or is there?
Thanks,
Nikolay

You could store the last selected option for each user in the database. Then you implement an AuthenticationSuccessHandler that reads the stored option from the database and sets it in the security context. If the option is not found, the user is redirected to the selection screen.
This should work regardless of the authentication type (form, basic or remember-be) only if you are using Spring Security 3.1 or later, as the possibility to register an AuthenticationSuccessHandler has been introduced in that version. There's a discussion on this topic in the Spring Forums.

Related

Grails - Spring Security Core onAuthenticationSuccess

I have a form that allows a user to either login or register.
When the user lands on the page containing the form, the request is saved in a RequestCache object (I'm using Spring Security).
In the case that the user decides to register, I want to mimic the behavior of the Spring Security onAuthenticationSuccess code, where the user is redirected to whatever page they were trying to get to before logging in (or, in my case, before registering).
To accomplish that, I added the following code to the RegistrationController:
authenticationSuccessHandler.onAuthenticationSuccess(request, response, springSecurityService.authentication)
My question is, is this a reasonable approach to handle the on registration success use case? Am I doing enough?
Best way would be to keep a link to the original requested URL in a hidden formitem on the registration page and redirect after registration. Try to keep the security layer as simple and close to the original intend as possible.

Spring security based application having both form login and SSO

I have searched enough but I haven't got a clear answer and thus posting this question.
I have an existing application which uses spring security for authentication.
Current implementation uses a custom implementation of UsernamePasswordAuthenticationFilter for doing this.
Thus the flow is something like below(in very simple terms):
inputrequest>DelegatingFilterProxy>LoginUrlAuthenticationEntryPoint>CustomUsernamePasswordAuthenticationFilter>AuthenticationManager>CustomAuthenticationProvider
Now I have a requirement to implement SSO (since the user is already asusmed to be authenticated) in some scenarios.
The requirement states that if I have a specific request parameter present then I need to automatically authenticate the request without bothering about user/password.
So it is same set of resources and I do not have to authenticate user/password if the specific SSO related request parameter is present.
e.g
suppose a resource \test\bus is a secure resource.
if I come from normal way then we need to check if the user is authenticated or nor and force user to put valid user/password
if I come from SSO channel then I need to show the \test\bus resource as the user is already authenticated.
currently all the access restrictions are put through <http> element
e.g the snippet of security-config.xml is as follows:
Query: What options do I have in this case. I can think of below options:
Pre-authenticate the user before spring security framework kicks in. This will mean creating an authentication token and putting in spring context before spring security filter is called. This can be done through another filter which is called before spring security filter chain. I have tested it and it works.
Create another custom security filter which set-up the authentication token. I am not clear if this is correct approach as not sure when do we create multiple custom security filter
Create another custom authentication provider e.g SSOCustomAuthenticationProvider. This provider will be called in the existing current flow as we can have multiple authentication providers to a authentication manager. The only issue is that in order to achieve this I have to change the request url to authentication filter's target url so that spring security doesn't check for authentication.
to explain more,
let's say request uri is /test/bus, I will write a filter which will intercept the request and change it to /test/startlogin. This is currently my CustomUsernamePasswordAuthenticationFilter's target url i.e
<property name="filterProcessesUrl" value="/test/startlogin"/>
The flow will be
inputrequest>DelegatingFilterProxy>LoginUrlAuthenticationEntryPoint>CustomUsernamePasswordAuthenticationFilter>AuthenticationManager>SSOCustomAuthenticationProvider
I have tested this and this works. Is this a valid approach or a hack.
Is there any other viable option available with me.
Thanks for reading this.

ASP.NET MVC: A PreAuthorize-like event, Good throttle point for concurrent logons?

I want to allow a new login to 'kick' a prior login session by the same account, in ASP.NET MVC.
It seems pretty clear that I'll give each browser a cooking representing the session ID. I'll track the currently active session ID in a server-side cache. If an already-active user attempts to log in, I'll verify the business logic (username, password, has been at least 15 minutes since last activity), and then update the active session ID cached at the server.
Now my issue is, a browser is holding an invalid session ID. What is the best point for me to inject a rejection or redirect to sign-in for this scenario?
I could modify the AuthorizeAttribute, but it seems like there should be a cleaner place to do this that won't require me to search and replace all my Authorize attributes, for example via a Global.asax event, or a controller event (I've already extended Controller in my project).
For example, if PreAuthorize existed, I would write some code there to test the request's cookies for a valid user/session ID pair, and if it didn't exist, I could simply remove the authentication cookie from the request, which would result in a standard unauthorized redirection.
So after a bit of research, it seems that a custom AuthorizeAttribute would typically be the correct approach. However, in my case, since I already had a custom role provider implemented, it was just a line of code to do it there. This also benefited me because I only wanted session concurrency for a single role. A side effect is that any use of web.config to control access to static files by role is also in-effect for session concurrency.

Manually Supply Referral URL to Spring Security

We have some shopping cart pages which work with both guest and user paths. We want to allow a user to login at any time during the process but don't really want to create yet another login page. I'd prefer that we can simply redirect the user to the existing login and tell Spring Security what URL to come back to.
I know this happens automatically when sessions timeout and/or protected pages are requested without a session, but is there a way I can give the URL to Spring Security myself?
If you just need a simple return-to URL to retrieve the cart, then you are probably best to implement that yourself in an AuthenticationSuccessHandler. You can look at the source for SimpleUrlAuthenticationSuccessHandler and its parent for inspiration.
The default login mechanism uses the RequestCache and a SavedRequest, but that is intended to actually replay a request which would not otherwise be authorised. That's probably overkill in your case.

Remember me in Spring security to remember only user-name

I am using Spring security in my application and wish to know if there is a way to "ask" spring to only remember the user-name of the user that comes to the application (by means of the remember-me checkbox).
What I could gather from the reference documentation is that Spring is able to save the userName and the password of the user, and directly log him/her in the next time. But what I want is that user be taken to the login page each time he comes back, but with his user-name already typed in.
Ofcourse if Spring doesn't have a way to do this, I would need to implement some cookie storage logic to take care of this requirement.
Many thanks for your answers as always.
So, you need to set a cookie containing the user name after authentication, and access it during rendering of the login page.
If you use Spring Security 3.x, the former can be done by subclassing AuthenticationSuccessHandler (SavedRequestAwareAuthenticationSuccessHandler is the default implementation) and setting a cookie with response.addCookie().
The latter is a regular cookie access (request.getCookies(), etc).

Resources