10.5 Remember-Me Authentication
5.5.1概览
Remember-me与 UsernamePasswordAuthenticationFilter 一起使用,并通过 AbstractAuthenticationProcessingFilter 超类中的钩子实现。它也应用于 BasicAuthenticationFilter。钩子将在适当的时间调用具体的 RememberMeServices 。界面如下:
Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
void loginFail(HttpServletRequest request, HttpServletResponse response);
void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication);
请参考JavaDoc以更全面地讨论方法的作用,注意,尽管在这个阶段 AbstractAuthenticationProcessingFilter 只调用LoginFail()和LoginsAccess()方法。每当 SecurityContextholder 不包含一个 Authentication 时,RememberMeAuthenticationFilter 就会调用 autologin() 方法。因此,此接口为基础的remember-me实现提供了与身份验证相关事件的充分通知,并在候选Web请求可能包含cookie并希望被记住时委托给实现。这种设计允许任何数量的“remember-me”实现策略。上面我们已经看到了Spring Security 提供了两种实现。我们依次看这些。
TokenBasedRememberMeServices
此实现支持第10.5.2节 “Simple Hash-Based Token Approach” 中描述的更简单的方法。TokenBasedRememberMeServices 生成一个RememberMeauthenticationToken,由RememberMeauthenticationProvider 处理。此身份验证提供程序和 TokenBasedRememberMeServices 之间共享key。此外,TokenBasedRememberMeServices 需要一个 UserDetailsService ,它可以从中检索用于签名比较的用户名和密码,并生成 RememberMeAuthenticationToken 以包含正确的 GrantedAuthority s。应用程序应提供某种注销命令,以使用户请求以后使cookie失效。TokenBasedRememberMeServices 还实现了Spring Security的 LogoutHandler 接口,因此可以与 LogoutHandler 一起使用,以便自动清除cookie。
应用程序上下文中启用“记住我”服务所需的bean如下:
<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>
不要忘记将 RememberMeServices 实现添加到您的UsernamePasswordAuthenticationFilter.setRememberMeServices()属性中,在AuthenticationManager.setProviders()列表中包含RememberMeAuthenticationProvider,并将RememberMeAuthenticationFilter添加到您的FilterChainProxy 中(通常在您的UsernamePasswordAuthenticationFilter之后)。
PersistentTokenBasedRememberMeServices
此类的使用方式与 TokenBasedRememberMeServices相同,但它还需要配置一个 PersistentTokenRepository 来存储令牌。这里有两种标准实现。
InMemoryTokenRepositoryImpl,仅用于测试。
JDBCtokenRepositoryImpl,它将令牌存储在数据库中。
上面第10.5.3节 “Persistent Token Approach”. 描述了数据库模式。