本文为转载学习
原文链接:http://blog.csdn.net/dsundsun/article/details/11826995
作为一个网站来说,记住密码功能是必不可少的,spring security也帮我们实现了这个功能。
看这段配置:
<http auto-config="true" use-expressions="true" > <intercept-url pattern= "/login.do" access="permitAll" /> <intercept-url pattern= "/*" access="hasRole('ROLE_USER')" /> <form-login login-page="/login.do" /> <logout logout-url="/logout" logout-success-url="/" /> <remember-me key= "jbcpPetStore"/> </http >
如果有了remember-me标签,我们怎么让他记住密码呢,肯定猜到了要一个拦截器去拦截一下。
我们猜到了,应该是使用_spring_security_remember_me这个参数,他就应该会被拦截到的。
看一下代码:
这样的话,就可以记住密码了。
那它是如何实现的呢?
Remember me功能设置了一个cookie在用户的浏览器上,它包含一个Base64编码的字符串,包含以下内容:
1.用户的名字;
2.过期的日期/时间
3.一个MD5的散列值包括过期日期/时间、用户名和密码
4.应用的key值,是在<remember-me>元素的key属性中定义的
这些内容将被组合成一个cookie的值存储在浏览器中以备后用。
也就是说spring security提供的remember me功能还是一样存储到cookie中。
关于remember me的cookie,我们能够看到这个cookie的组成足够复杂,所以对攻击者来
说很难造出一个仿冒的cookie。在第四章中,我们将会学习另一种技术来使得remember me
功能更加安全,免受恶意攻击。
那么rememberme的功能是实现的,他使用的是哪个过滤器呢?其实是o.s.s.web.authentication.rememberme.RememberMeAuthenticationFilter过滤器,他会拦截remember-me请求,并且进行处理.让我们看一下这个具体过程:
从上图可以看出RememberMeAuthenticationFilter依赖一个o.s.s.web.authentication.RememberMeServices来进行具体的校验操作。看到这里,觉得spring security的设计很有意思,每次拦截器都只会拦截请求然后交给别人处理(真实懒啊).不过好的分工和设计,有助于代码的重构行和可读性,也会降低程序的耦合性,非常棒!
我们继续来看<remember-me>标签的属性:
书中建议我们让key足够复杂,最好使用密码随机发生器(online password generator),我们可以搜索一下,然后生成一个随机key;
【设置remember me的会话cookie:如果token-validity-seconds属性被设置成-1,登录cookie将被设置为会话cookie,即在用户关闭浏览器后不会被保存。Token的有效时间是一个不可配置的值为2周(假设用户不关闭浏览器)。不要将这个cookie与存储用户的session ID的cookie相混淆——它们是不同的事情却有着类似的名字。】
这里涉及到了一个完整认证的概念(这可以通过使用SpEL表达式语言的fullyAuthenticated伪属性来实现),
其实我们可以这样想,对于一个remember-me的用户,每次都可以访问到授权的页面,那样是不合理的,不如有一个哥们用了你的电脑,也是在本地登录了你的账号,他是不是也可以看到你的隐私了呢?这显然不对,对于你的隐私的文件,我们需要完整认证,什么叫完整认证呢,就是说,即使你使用了remember-me登录了,当你访问私密性较高的文件时,还是需要再次验证一次。
配置方式如下:
<intercept-url pattern="/account/*.do" access="hasRole('ROLE_USER') and fullyAuthenticated"/>
以上是spEL表达式的配法(非常灵活,可以使用逻辑,我们建议使用spEL的方式)
还有一种方式:access=" IS_AUTHENTICATED_FULLY"(不是太灵活,所以不提倡这么做!)