职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 982|回复: 1

SpringSecurity3.X--remember-me

[复制链接]
月上萧萧 发表于 2011-8-30 10:01 | 显示全部楼层 |阅读模式
笔者在SpringSecurity中配置remember-me时,遇到这样的问题,remember-me没有起作用,安照官方文档的讲解,只需要在<http>中增加<remember-me />配置,并在login.jsp中增加如下代码即可:
  
<input id="_spring_security_remember_me" name="_spring_security_remember_me" type="checkbox" value="true"/>  

<input id="_spring_security_remember_me" name="_spring_security_remember_me" type="checkbox" value="true"/>  
看上去挺简单的,可是笔者测试后发现并未起作用,google了一下,也未见有人提起过该问题,于是乎翻出源码一探究竟,果然发现了问题。

这里先简要说明一下SpringSecurity的登录过程:
  
UsernamePasswordAuthenticationFilter :获得用户提交的用户名和密码信息   
-->UserDetailsService :由其封装用户对象   
-->AbstractUserDetailsAuthenticationProvider :转由其进行密码和权限验证,验证通过后封装一个Authentication   
--><SPAN style="COLOR: #ff0000"><STRONG>ProviderManager</STRONG>   
</SPAN>   
:会将Authentication封装到SecurityContext中(默认情况下,ProviderManager会在认证成功后清除掉Authentication的密码信息,但会保留用户名称)   
-->AbstractRememberMeServices :判断请求参数中是否包含_spring_security_remember_me参数,如果包含并且值为(true,on,yes,1)中的任意一个,则将用户名和密码信息保存进cookie,否则不做处理   
-->AccessDecisionManager :由其决定是否放行   
  
之后在请求被保护的资源时,RememberMeAuthenticationFilter会先判断是否Authentication已经失效,如果失效,则试图从cookie中寻找,找到则重新封装Authentication。  

UsernamePasswordAuthenticationFilter :获得用户提交的用户名和密码信息
-->UserDetailsService :由其封装用户对象
-->AbstractUserDetailsAuthenticationProvider :转由其进行密码和权限验证,验证通过后封装一个Authentication
-->ProviderManager

:会将Authentication封装到SecurityContext中(默认情况下,ProviderManager会在认证成功后清除掉Authentication的密码信息,但会保留用户名称)
-->AbstractRememberMeServices :判断请求参数中是否包含_spring_security_remember_me参数,如果包含并且值为(true,on,yes,1)中的任意一个,则将用户名和密码信息保存进cookie,否则不做处理
-->AccessDecisionManager :由其决定是否放行

之后在请求被保护的资源时,RememberMeAuthenticationFilter会先判断是否Authentication已经失效,如果失效,则试图从cookie中寻找,找到则重新封装Authentication。
问题就出在ProviderManager中,其布尔属性eraseCredentialsAfterAuthentication默认值为true,如果未true则会在username和password验证成功后清除掉Authentication中的password信息,而AbstractRememberMeServices 保存cookie的条件则需要从Authentication要同时取得username和password,这就导致默认情况下AbstractRememberMeServices永远不会将username和password存储到cookie中,所以,为了保证username和password可以被正确的存储到cookie中,我们需要修改eraseCredentialsAfterAuthentication的值为false,好在修改这个属性很方便,如下:
  
<authentication-manager <SPAN style="COLOR: #ff0000">erase-credentials="false"</SPAN>   
>   
        <authentication-provider user-service-ref="userService">   
            <password-encoder hash="md5" />   
        </authentication-provider>   
</authentication-manager>  

<authentication-manager erase-credentials="false"
>
                <authentication-provider user-service-ref="userService">
                        <password-encoder hash="md5" />
                </authentication-provider>
</authentication-manager>
增加该配置后,则cookie信息被成功保存。

默认情况下,cookie的有效期为两个星期,如果希望修改这个有效期,可以在<remember-me />中进行配置:
Xml代码  
<remember-me  token-validity-seconds="123456789"/>  

<remember-me  token-validity-seconds="123456789"/>  

不知道为什么ProviderManager要这样处理,也许是我还没搞清楚缘由,希望与各位讨论。

木已 发表于 2011-8-30 10:01 | 显示全部楼层
推荐链接
3G培训就业月薪平均7K+,不3K就业不花一分钱!
20-30万急聘多名天才Java/MTA软件工程师
见证又一个准百万富翁的诞生!


您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-5 14:51 , Processed in 0.127535 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表