我正在尝试使用Spring在我的网站上实现“记住我”功能。正确创建了persistent_logins表中的cookie和条目。此外,我可以看到正在恢复正确的用户,因为用户名显示在页面顶部。
但是,一旦我在“记住”它们返回后尝试访问该用户的任何信息,我就会得到一个NullPointerException。看起来用户没有再次在会话中设置。
我的applicationContext-security.xml包含以下内容:
<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=?"/>
我认为它可能与用户逐个用户名的查询有关,但如果此查询不正确,肯定登录无法正常工作?
对此的任何帮助将不胜感激。
谢谢, gearoid。
答案 0 :(得分:4)
是否可以包含异常的整个堆栈跟踪?我怀疑因为你没有在上面指定的remember-me配置上设置key属性,所以没有在SecurityContextHolder上设置令牌。
要查看Remember Me如何工作的详细信息,您应该查看RememberMeAuthenticationFilter的来源。你可以在这里找到这个来源(直接):
RememberMeAuthenticationFilter将作为以下结果调用RememberMeAuthenticationProvider:
rememberMeAuth = authenticationManager.authenticate(rememberMeAuth);
在authenticate方法中,您可以看到如果您未指定密钥,它将引发异常:
if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication).getKeyHash()) {
throw new BadCredentialsException(messages.getMessage("RememberMeAuthenticationProvider.incorrectKey",
"The presented RememberMeAuthenticationToken does not contain the expected key"));
}
密钥可以字面上是任何字符串“your-company-name- {GUID}”或类似的东西。那么你记得我会更像这样:
<remember-me key="your-company-name-rmkey-aWeFFTgxcv9u1XlkswUUiPolizxcwsqUmml" token-validity-seconds="3600" data-source-ref="dataSource"/>
设置令牌有效性是一个非常好的主意,你应该这样做。
捐赠