Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with Remember Me Service in Spring Security

Tags:

I'm trying to implement a "remember me" functionality in my website using Spring. The cookie and entry in the persistent_logins table are getting created correctly. Additionally, I can see that the correct user is being restored as the username is displayed at the top of the page.

However, once I try to access any information for this user when they return after they were "remembered", I get a NullPointerException. It looks as though the user isn't being set in the session again.

My applicationContext-security.xml contains the following:

<remember-me data-source-ref="dataSource" user-service-ref="userService"/>

...

<authentication-provider user-service-ref="userService" />

<jdbc-user-service id="userService" data-source-ref="dataSource" 
role-prefix="ROLE_"
users-by-username-query="select email as username, password, 1 as ENABLED from user where email=?" 
authorities-by-username-query="select user.id as id, upper(role.name) as authority from user, role, users_roles where users_roles.user_fk=id and users_roles.role_fk=role.name and user.email=?"/>

I thought it may have had something to do with users-by-username query but surely login wouldn't work correctly if this query was incorrect?

Any help on this would be greatly appreciated.

Thanks, gearoid.

like image 226
Gerard Avatar asked Mar 16 '10 10:03

Gerard


People also ask

What is Remember Me in Spring Security?

Remember me is a feature that allows a user to access into application without re-login. User's login session terminates after closing the browser and if user again access the application by opening browser, it prompts for login.

What is true about Isauthenticated Remember me?

isAnonymous(Authentication) is false and AuthenticationTrustResolver. isRememberMe(Authentication) is false. The "REMEMBERED" will grant access if the principal was either authenticated via remember-me Or is fully authenticated.


1 Answers

Can you please include the entire stack trace of the exception? I suspect that because you have not set the key attribute on the remember-me configuration that you specified above that the token is not being set on the SecurityContextHolder.

To see details of how Remember Me works you should take a look at the source for the RememberMeAuthenticationFilter. You can find that source here (directly):

http://grepcode.com/file/repo1.maven.org/maven2/org.springframework.security/spring-security-web/3.0.2.RELEASE/org/springframework/security/web/authentication/rememberme/RememberMeAuthenticationFilter.java

RememberMeAuthenticationFilter is going to call in the RememberMeAuthenticationProvider as a result of:

rememberMeAuth = authenticationManager.authenticate(rememberMeAuth);

Inside the authenticate method you can see that it will throw an exception if you do not specify a key:

 if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication).getKeyHash()) {
            throw new BadCredentialsException(messages.getMessage("RememberMeAuthenticationProvider.incorrectKey",
                    "The presented RememberMeAuthenticationToken does not contain the expected key"));
        }

The key can literally be any string "your-company-name-{GUID}" or something like that. So then your remember-me would look more like this:

<remember-me key="your-company-name-rmkey-aWeFFTgxcv9u1XlkswUUiPolizxcwsqUmml" token-validity-seconds="3600" data-source-ref="dataSource"/>

Setting the token-validity is a really good idea which you should do.

Grant

like image 94
Grant Cermak Avatar answered Nov 15 '22 05:11

Grant Cermak