spring security3.x学习(12)_remember me

本文为转载学习

原文链接: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 security3.x学习(12)_remember me_第1张图片

我们猜到了,应该是使用_spring_security_remember_me这个参数,他就应该会被拦截到的。

看一下代码:

spring security3.x学习(12)_remember me_第2张图片

这样的话,就可以记住密码了。

那它是如何实现的呢?

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请求,并且进行处理.让我们看一下这个具体过程:

spring security3.x学习(12)_remember me_第3张图片

从上图可以看出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"(不是太灵活,所以不提倡这么做!)


你可能感兴趣的:(SpringSecurity)