Remember me in Spring security to remember only user-name - spring-security

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

Related

JSESSIONID use existing session cookies

Spring Session uses a different format for its session cookies than Tomcat does. So if you implement Spring Session, even if you would name the session cookie JSESSIONID, all the users have to login again.
This is a point where you potentially lose users, because nobody likes to login. Perhaps this is an edge case, and certainly it's not worth a huge amount of trouble, but I'm curious if it's possible for existing users to use their already stored Tomcat session cookies?
You can implement your own org.springframework.session.web.http.CookieSerializer that matches Tomcat's default cookie serialization and register it as a bean.
Spring Session configuration will then pick it up and use it - see org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration#setCookieSerializer for more details.

Using a Custom Single Sign On Authentication Service with Spring Security Core Plugin

I'm working on a Grails application and want to integrate with a custom single-sign-on service (not CAS, but similar). I'm struggling to find all the pieces that I need to customize to make this happen. Can someone explain to me a general outline as to what I need to use to accomplish this? I've read the documentation on the plugin, but it assumes I know which beans to override and where to put all the needed files.
I've block-quoted what I think needs to be done based on my research below each point.
Order of Operations
1- The user requests secure content (everything is secure in the application for now)
I believe this setting is in the Config.groovy file:
grails.plugins.springsecurity.rejectIfNoRule = true
grails.plugins.springsecurity.securityConfigType = "InterceptUrlMap"
grails.plugins.springsecurity.interceptUrlMap = [
'/**':['ROLE_ADMIN']
]
2- Spring Security checks to see if the user has a specific value set in a cookie provided by the authentication service
I'm guessing I need to create an authentication filter, but I don't know where to put it or what it should look like.
If they don't, the user is redirected to this custom SSO service, they login, once authenticated, the user is redirected back to my application (with a new cookie set)
3- Spring security checks for the cookie value and validates it against the custom service (via HTTP POST)
From some research, I think that I need to use PreAuthenticatedProcessingFilter, but I haven't been able to find any examples of how to do this.
4- The custom service returns a series of name/value pairs, a user then needs to be created in the local application database (or the timestamp of "lastLoggedIn" is updated if they user's data is already in the database)
I believe this is done in the same PreAuthenticatedProcessingFilter as number 3 or in a GrailsUserDetailsService
5- The user's authentication is cached in the session for a period of time (6-8 hours) so that re-validation against the SSO service doesn't need to occur every time the user requests a new resource.
I'm not sure if this is something that's done inherently or if I need to add code to do this (and also set the session timeout)

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 functionality for 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.

External authentication using Spring Security

We got our own central session management. Generally user can authenticate over it with an username and password, and as a result he gets an session_id. All other operations are done with that session_id. Let's say that the session management is accessed by a XML RPC.
I have two cases to implement:
Central web application made in Spring, which has login form
External web applications also made in Spring, which are relying on
passed session_id only.
Few more notices regarding system:
- session_id is stored in a cookie (after successful login, I have to add cookie to a response)
- every page request has to check session_id validity in session management system
I'm quite new to Spring, so I'm struggling to understand where and how to implement my custom logic.
My questions are:
What parts of a system I have to implement to have my own login
logic (got to have access to a response object too - to set cookie)?
I tryed something with extending UsernamePasswordAuthenticationFilter and implementing my own
AuthenticationManager, but I'm not sure that I'm going the right
way.
Is there point where/how can I implement my "every request session
check" in Spring Security manner?
session_id is stored in a cookie (after successful login, I have to add cookie to a response)
Do this in a AuthenticationSuccessHandler that is configured into your <form-login> element:
<form-login authentication-success-handler-ref="authenticationSuccessHandler"/>
External web applications also made in Spring, which are relying on passed session_id only.
Create a new filter where you check for the session_id cookie. If the cookie is not present or if it is invalid redirect to the central web application for the user to log in. If the cookie is present and valid and the user isn't already authenticated then create a new Authentication and add it to the SecurityContextHolder.
Take a look at RememberMeAuthenticationFilter.doFilter() for an example of what you want to do in your filter.
Add this filter to the filter chain using the <custom-filter> element.

Resources