实施Remember-Me认证
原文:
http://tech.it168.com/j/2007-11-05/200711051740968_2.shtml
一、Remember-Me认证功能介绍
很多网站的用户登录页面都提供了一个类似于“两周内不用再登录”、“记住我的帐号”等功能,其原理是在用户登录成功后使用客户端浏览器的Cookie记录用户登录信息,当下次再访问相同站点时,直接从Cookie中取得用户登录信息并进行自动登录。这即是经典的Remember-Me的功能,该功能在一定程度上降低了用户频繁登录的麻烦。根据系统安全性需求的不同,Remember-Me可能在Cookie中保存用户名/密码或仅保存用户名,前者可以完成自动登录,而后者只是让用户避免输入用户名。
如果在Cookie中记录用户名/密码,虽然可以避免每次访问网站都进行登录的麻烦,但这把双刃剑的反面是黑客可以在一定条件下获取这个免检的通行证。为了在给用户带来便利的同时尽力降低潜在的风险,Cookie保存用户名/密码的方式变得非常关键,以下几点是必须考虑的问题:
1) Cookie是易受攻击的,多用户共享浏览器和跨站点脚本攻击都可能使Cookie失窃;
2)将用户名/密码保存在Cookie中,意味着用户可以在不显式进行登录的情况下,获取正常登录的一切权限;
3)一切可以从Cookie中反推出密码明文的存储方式都是不可接受的;
4)必须将客户端IP信息绑定在Cookie中,这样即使Cookie失窃,也不可能在其它机器使用。
如果说HttpSessionContextIntegrationFilter通过HttpSession使Authentication获得跨请求共享的能力,那么Remember-Me则通过Cookie使Authentication获得跨多个Session的能力。Remember-Me功能可以视为一套解决方案,以下是Remember-Me中最关键的三个问题:
1) 在用户登录时,获取用户名/密码的信息,并将其以一定方式保存到Cookie中;
2) 在Cookie有效时间内,当用户访问站点安全页面时,自动进行登录;
3) 必须提供一个功能,让用户可以手工清除Remember-Me Cookie。
org.acegisecurity.ui.rememberme.RememberMeServices是Remember-Me方案中最关键的一个接口,它定义了以下几个方法:
l void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication):登录成功后调用该方法,将用户名/密码保存到Cookie中;
l void loginFail(HttpServletRequest request, HttpServletResponse response):登录失败后调用该方法;
l Authentication autoLogin(HttpServletRequest request, HttpServletResponse response):从Cookie中自动获取用户名/密码进行自动登录。
loginSuccess()和loginFail()方法的调用已经编制到Acegi的AbstractProcessingFilter抽象过滤器中,这意味着任何注入了RememberMeServices实例的过滤器都会以适合的方式调用这两个方法。而autoLogin()方法则通过RememberMeProcessingFilter进行调用,当RememberMeProcessingFilter发现SecurityContextHolder中不存在有效的Authentication时,autoLogin()方法就会被执行。
Acegi为RememberMeServices接口提供了两个实现类,它们分别是:
l NullRememberMeServices:类似于适配器的实现类,它不做任何有意义的事情,这是AbstractProcessingFilter中默认的实现类;
l TokenBasedRememberMeServices:基于凭证(一般指用户名/密码)的Remember-Me实现类,它真实地实现了接口中的方法。
二、Remember-Me认证的代码实现
在登录时将用户名/密码记录到Cookie中
我们第一个要做的工作是通过调整AuthenticationProcessingFilter的配置,在处理用户登录页面提交的用户认证信息时,将用户名/密码通过Response记录到客户端的Cookie中:
代码清单 12 applicationContext-acegi-security.xml
记录Remember-Me的Cookie信息
…
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
…
①注入一个RememberMeServices
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<bean id="rememberMeServices" ②RememberMeServices配置
class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="tokenValiditySeconds" value="432000"/> ②-1Cookie有效时间,单位为秒
<property name="key" value="baobaotao"/> ②-2 Cookie中的键值
</bean>
…
三、Remember-Me认证的代码分析
(1)
通过以上的配置,我们在处理用户登录的同时将用户名/密码的信息记录到Cookie中。authenticationProcessingFilter在完成用户身份认证后,如果认证成功,调用rememberMeServices的loginSuccess()方法,该方法将用户名/密码按以下方式进行编码,编码后再写到客户端的Cookie中:
base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":"+password + ":" + key))
base64()表示进行BASE64编码操作,而md5Hex()表示进行MD5摘要并将结果值以HEX(十六进制)进行编码。注意计算式中粗体所示key操作项,Acegi通过key防止整个加密串被恶意篡改。因为key是在服务端中指定的值,黑客无法进行猜测,在服务端通过如②-2所示的key属性指定该值。
(2)
Cookie的有效时间通过tokenValiditySeconds指定,默认为两个星期。②-1处我们显式指定为5天(对应的秒数)。
(3)
我们知道authenticationProcessingFilter处理对应/j_acegi_security_check的请求,我们应该让用户决定是否使用Remember-Me的功能,这可以通过一个名为“_acegi_security_remember_me”的HTTP参数来决定,当登录请求表单包含该参数时(勾选上对应的复选框),服务端认为需要启用Remember-Me功能,否则不启用Remember-Me功能。所以,我们必须相应地调整登录页面表单。
四、index.jsp:添加是否使用Remember-Me功能的控制参数
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
…
<form name="form1" method="post" action="<c:url value="/j_acegi_security_check"/>">
用户名:<input type="text" name="j_username"/><br/>
密 码:<input type="password" name="j_password"/><br/>
①用户可以通过勾选或取消该复选框决定是否启用Remember-Me功能
<input type="checkbox" name="_acegi_security_remember_me">5天内不用再登录
<input type="submit" value="登录"/>
</form>
…
分享到:
相关推荐
- **将Remember-me功能迁移至数据库**:探讨了如何将Remember-me的功能与数据库结合,以提供更安全的会话管理。 ### 第五章:精确的访问控制 本章聚焦于如何实施更精细化的访问控制策略。 - **重新思考应用功能和...
通过以上详细解析,可以看出Spring Security是一个非常强大且灵活的安全框架,它不仅能够满足基本的认证需求,还提供了丰富的高级特性,如权限管理、Remember-Me功能、session管理等。这对于构建安全可靠的企业级...
4. **Remember-Me服务**: - Spring Security 提供了Remember-Me服务,允许用户在一段时间内无需再次输入密码即可访问应用。这通过存储在cookie中的令牌实现,增强了用户体验。 5. **CSRF保护**: - 默认情况下,...
- Spring Security提供了多种实现方式,如基于令牌的Remember-Me服务。 8. **异常处理**: - 自定义错误页面:当用户尝试访问未经授权的资源时,Spring Security会抛出相应的异常,你可以配置自定义的错误页面...
- **Remember-me功能**:自动记住用户的登录状态,用户再次访问时无需重复登录,但需考虑其安全性。 - **修改密码管理**:提供修改密码的功能,同时确保密码的存储和传输安全。 #### 四、凭证安全存储 - **使用...
- 使用Remember-Me服务实现持久化会话,使用户在关闭浏览器后仍能保持登录状态。 - OAuth2和OpenID Connect集成,为现代Web应用提供社交登录功能。 3. **授权模型**: - 角色与权限的概念,以及如何在Spring ...
此外,Spring Security还支持基于Remember Me的功能,允许用户在一段时间内无须重新登录。这通常通过`remember-me`元素来配置: ```xml ... <remember-me key="yourUniqueKey" user-service-ref="userService"/>...
5. **记住我功能**(Remember-Me): - 用户选择"记住我"时,SpringSecurity能自动在下次访问时进行身份验证,手册会讲解如何实现这一功能。 6. **会话管理**: - **SessionManagementConfigurer**:防止会话固定...
3. **RememberMe功能**: RememberMe功能允许用户在一段时间内无需重新登录。CAS支持RememberMe,通过在用户登录时设置持久化的cookie,实现下次自动登录。文件"CAS RememberMe功能实现 - waitingmyself的日志 - ...
这里`/rememberMe=rememberMe`表示在`/rememberMe`请求上应用`RememberMeProcessingFilter`。 4. **前端处理**: 在登录页面中,需要添加一个复选框供用户选择是否启用“记住我”功能,并在表单提交时将该选项...
这些过滤器在HTTP请求到达控制器之前进行拦截,执行认证和授权等安全检查,如Remember-Me服务用于自动登录,SessionManagementFilter则负责会话管理,防止会话固定攻击。 此外,手册还涵盖了Spring Security的扩展...
此外,Acegi 还支持记住我(Remember-Me)功能,允许用户在一段时间内无需重新登录。这通过生成和存储持久化的安全令牌实现,确保即使用户关闭浏览器,下次打开时仍能自动登录。然而,记住我功能必须谨慎使用,因为...
32.3.3使用CAS认证无状态服务 249 配置CAS以获取代理授予票证 249 使用代理票证调用无状态服务 250 32.3.4代理票证认证 251 33. X.509认证 253 33.1概述 253 33.2将X.509身份验证添加到您的Web应用程序 253 33.3在...
- **Remember-Me功能**:通过cookies实现,允许用户在关闭浏览器后仍保持登录状态。这不仅提升了用户体验,同时也需谨慎处理,避免成为安全漏洞。 - **每次请求验证登录**:通过在每次HTTP请求时验证session,可以...