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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With