浏览 3932 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-02
14.1. 概述 记住我(remember-me)或持久登录(persistent-login)认证,指的是网站可以在不同会话之间记忆验证的身份。 通常情况是发送一个cookie给浏览器,在以后的session里检测cookie,进行自动登录。 Spring Security为remember-me实现提供了必要的调用钩子,并提供了两个remember-me的具体实现。 其中一个使用散列来保护基于cookie标记的安全性,另一个使用了数据库或其他持久化存储机制来保存生成的标记。 注意,两个实现方式,都需要UserDetailsService。 如果你使用了认证提供器,没有使用UserDetailsService(比如LDAP供应器),那它就没法工作,除非你在application context里设置了一个UserDetailsService。 14.2. 简单基于散列标记的方法 这种方法使用散列来完成remember-me策略。 本质上,在成功进行认证的之后,把一个cookie发送给浏览器,使用的cookie组成结构如下: base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key)) username: As identifiable to the UserDetailsService password: That matches the one in the retrieved UserDetails expirationTime: The date and time when the remember-me token expires, expressed in milliseconds key: A private key to prevent modification of the remember-me token 这个remember-me标记只适用于指定范围,提供用户名,密码和关键字都不会改变。 值得注意,这里有一个潜在的安全问题,来自任何一个用户代理的remember-me标记,直到标记过期都是可用的。 这个问题和摘要式认证相同。 如果一个用户发现标记已经设置了,他们可以轻易修改他们的密码,并且立即注销所有的remember-me标记。 如果需要更好的安全性,你应该使用下一章描述的方法。 或者不应该使用remember-me服务。 如果你还记得在命名空间配置中讨论的主题,你只要添加<remember-me>元素就可以使用remember-me认证: <http> ... <remember-me key="myAppKey"/> </http> 如果你使用了auto-config设,它也会自动启用。 这个UserDetailsService会自动选上。 如果你在application context中配置了多个,你需要使用user-service-ref属性指定应该使用哪一个,这里的值要放上你的UserDetailsService bean的名字。 14.3. 持久化标记方法 这个方法是基于这篇文章 http://jaspan.com/improved_persistent_login_cookie_best_practice 进行了一些小修改 [3]。 要用在命名空间配置里使用这个方法,你应该提供一个datasource引用: <http> ... <remember-me data-source-ref="someDataSource"/> </http> 数据应该包含一个 persistent_logins 表,可以使用下面的SQl创建(或等价物): create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null) 14.4. Remember-Me接口和实现 Remember-me认证不能和基本认证一起使用,因为基本认证往往不使用HttpSession。 Remember-me使用在AuthenticationProcessingFilter中,通过在它的超类AbstractProcessingFilter里实现的一个调用钩子。 这个钩子会在合适的时候调用一个具体的RememberMeServices。 这个接口看起来像这样: Authentication autoLogin(HttpServletRequest request, HttpServletResponse response); void loginFail(HttpServletRequest request, HttpServletResponse response); void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication); 请参考JavaDocs获得有关这些方法的完整讨论,不过注意在这里,AbstractProcessingFilter只调用loginFail() 和 loginSuccess()方法。 当SecurityContextHolder没有包含Authentication的时候,RememberMeProcessingFilter才去调用autoLogin()。 因此,这个接口通过使用完整的认证相关事件的提醒提供了下面remember-me实现,然后在可能包含一个cookie希望被记得的申请web请求中调用这个实现。 这个设计允许任何数目的remember-me实现策略。 我们在下面看看上面介绍过的两个Spring Security提供的实现。 14.4.1. TokenBasedRememberMeServices 这个实现支持在Section 14.2, “简单基于散列标记的方法”里描述的简单方法。 TokenBasedRememberMeServices被 RememberMeAuthenticationProvider执行的时候生成一个RememberMeAuthenticationToken。 认证提供器和TokenBasedRememberMeServices之间共享一个key。 另外TokenBasedRememberMeServices需要一个UserDetailsService,用它来获得用户名和密码,进行比较,然后生成RememberMeAuthenticationToken来包含正确的GrantedAuthority[]。 如果用户请求注销,让cookie失效,就应该使用系统提供的一系列注销命令。 TokenBasedRememberMeServices也实现Spring Security的LogoutHandler接口,这样可以使用LogoutFilter自动清除cookie。 这些bean要求在application context里启用remember-me服务,像下面一样: <bean id="rememberMeProcessingFilter" class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter"> <property name="rememberMeServices" ref="rememberMeServices"/> <property name="authenticationManager" ref="theAuthenticationManager" /> </bean> <bean id="rememberMeServices" class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices"> <property name="userDetailsService" ref="myUserDetailsService"/> <property name="key" value="springRocks"/> </bean> <bean id="rememberMeAuthenticationProvider" class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider"> <property name="key" value="springRocks"/> </bean> 不要忘记把你的RememberMeServices实现添加到AuthenticationProcessingFilter.setRememberMeServices()属性中,包括把RememberMeAuthenticationProvider添加到你的AuthenticationManager.setProviders()队列中,把RememberMeProcessingFilter添加到你的FilterChainProxy中(要放到AuthenticationProcessingFilter后面)。 14.4.2. PersistentTokenBasedRememberMeServices 这个类可以像TokenBasedRememberMeServices一样使用,但是它还需要配置一个PersistentTokenRepository来保存标记。 这里有两个标准实现。 * InMemoryTokenRepositoryImpl最好是只用来测试。 * JdbcTokenRepositoryImpl把标记保存到数据库里。 数据库表结构在 Section 14.3, “持久化标记方法”. [3] 基本上,为了防止暴露有效登录名,用户名没有包含在cookie里。在这个文章的评论里有一个相关的讨论。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-10-28
怎么设置cookie失效的时间呢?比如两个星期
|
|
返回顶楼 | |