RememberMeProcessingFilter
该Filter会在用户登录后,在本地机器上记录用户cookies信息,这样下次访问就不用再登录了。它还负责对所有HTTP请求进行拦截,当发现SecurityContextHolder中没有包含有效的Authentication对象时,自动调用RememberMeServices#autoLogin()方法从Cookie中获取用户名/密码的编码串进行自动登录,所以rememberMeProcessingFilter首先要注入一个RememberMeServices Bean。
rememberMeProcessingFilter通过rememberMeServices获取对应Cookie中用户的UserDetails后,就必须进行用户身份认证。这项工作依然委托给authenticationManager完成,所以我们给rememberMeProcessingFilter注入了authenticationManager Bean。
authenticationManager如何对基于Cookie的用户凭证进行认证呢?显然,不能采用原来的daoAuthenticationProvider所用的方法,因为Cookie所提供用户凭证和登录表单提供的用户凭证在格式上存在很大的差异。基于Remember-Me的用户名/密码信息是经过特殊编码的字符串,Acegi通过RememberMeAuthenticationProvider负责对基于Cookie的用户凭证信息进行认证。所以你必须将该认证提供者添加到authenticationManager中。
该Filter会在用户登录后,在本地机器上记录用户cookies信息,这样下次访问就不用再登录了。它还负责对所有HTTP请求进行拦截,当发现SecurityContextHolder中没有包含有效的Authentication对象时,自动调用RememberMeServices#autoLogin()方法从Cookie中获取用户名/密码的编码串进行自动登录,所以rememberMeProcessingFilter首先要注入一个RememberMeServices Bean。
rememberMeProcessingFilter通过rememberMeServices获取对应Cookie中用户的UserDetails后,就必须进行用户身份认证。这项工作依然委托给authenticationManager完成,所以我们给rememberMeProcessingFilter注入了authenticationManager Bean。
authenticationManager如何对基于Cookie的用户凭证进行认证呢?显然,不能采用原来的daoAuthenticationProvider所用的方法,因为Cookie所提供用户凭证和登录表单提供的用户凭证在格式上存在很大的差异。基于Remember-Me的用户名/密码信息是经过特殊编码的字符串,Acegi通过RememberMeAuthenticationProvider负责对基于Cookie的用户凭证信息进行认证。所以你必须将该认证提供者添加到authenticationManager中。
- <bean id="rememberMeProcessingFilter"
- class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
- <property name="authenticationManager" ref="authenticationManager" />
- <property name="rememberMeServices" ref="rememberMeServices" /><!-- 增加 -->
- </bean>
- <bean id="authenticationManager"
- class="org.acegisecurity.providers.ProviderManager">
- <property name="providers">
- <list>
- <ref local="daoAuthenticationProvider" />
- <!-- 增加 -->
- <bean
- class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
- <property name="key" value="changeThis" />
- </bean>
- <!-- 增加 -->
- <bean
- class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
- <property name="key" value="foobar" /><!-- key必须和rememberMeServices中的key一致 -->
- </bean>
- </list>
- </property>
- </bean>
- <!-- 增加, 默认tokenValiditySeconds = 1209600L, 即保留两周 -->
- <bean id="rememberMeServices"
- class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
- <property name="userDetailsService" ref="inMemDaoImpl" />
- <!-- cookie中的键值, 防止保存到客户端的cookie中的加密串被恶意篡改 -->
- <property name="key" value="foobar" />
- <!-- cookie有效时间, 单位为秒, 这里设定为5天内不用再登陆 -->
- <property name="tokenValiditySeconds" value="432000" />
- </bean>
- 另外,必须在AuthenticationProcessingFilter中加入rememberMeServices。这样,当用户勾选了记住密码并登录后,rememberMeServices会将用户信息保存到Cookie中
- <bean id="authenticationProcessingFilter"
- class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
- ……
- <property name="rememberMeServices" ref="rememberMeServices" /><!-- 增加, 可别忘了此处 -->
- </bean>