根据Remember-Me进行自动登录
如果用户在登录时选择了Remember-Me的功能(即勾选“5天内不用再登录”复选框),登录成功后用户名/密码的信息就保存在客户机的Cookie中。下次用户直接访问站点的安全页面时,必须有一个过滤器能够自动调用RememberMeServices#autoLogin()完成自动登录的操作,这便是通过RememberMeProcessingFilter过滤器来完成的:
代码清单 14 applicationContext-acegi-security.xml
Remember-Me自动登录
<bean id="filterChainProxy"
class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
…
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
logoutFilter,rememberMeProcessingFilter ①处理自动登录的过滤器
</value>
</property>
</bean>
<bean id="rememberMeProcessingFilter" ②自动登录过滤器
class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>②-1
<property name="authenticationManager" ref="authenticationManager"/>②-2
</bean>
<bean id="rememberMeServices" ③
class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="tokenValiditySeconds" value="432000"/>
<property name="key" value="baobaotao"/>
<property name="userDetailsService" ref="userDetailsService" />③-1
</bean>
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<bean class="org.acegisecurity.providers.rememberme. ④
RememberMeAuthenticationProvider">
<property name="key" value=" baobaotao"/>
</bean>
</list>
</property>
</bean>
首先,我们在过滤器链中添加一个rememberMeProcessingFilter,它负责对所有HTTP请求进行拦截,当发现SecurityContextHolder中没有包含有效的Authentication对象时,自动调用RememberMeServices#autoLogin()方法从Cookie中获取用户名/密码的编码串进行自动登录。所以rememberMeProcessingFilter首先要注入一个RememberMeServices Bean,如②-1所示。
在 代码清单 12中已经定义了一个被AuthenticationProcessingFilter 使用的RememberMeServices Bean。我们在前面说过, AuthenticationProcessingFilter在注入RememberMeServices Bean后,就会在适合的时候调用RememberMeServices#loginSuccess()方法将用户凭证保存到Cookie中。而RememberMeProcessingFilter则会调用RememberMeServices#autoLogin()方法对保存在Cookie中的用户凭证执行自动认证的操作。前者是将Authentication中的用户名/密码写入到Cookie中,而后者需要据此获得对应的UserDetails,进而再重现出Authentication对象。正如你所想到的一样,RememberMeServices需要通过一个UserDetailsService来完成这项工作,所以我们需要调整RememberMeServices的配置,如③-1所示。
rememberMeProcessingFilter通过rememberMeServices获取对应Cookie中用户的UserDetails后,就必须进行用户身份认证。这项工作依然委托给authenticationManager完成,所以在②-2中,我们给rememberMeProcessingFilter注入了authenticationManager Bean。
authenticationManager如何对基于Cookie的用户凭证进行认证呢?显然,不能采用原来的daoAuthenticationProvider所用的方法,因为Cookie所提供用户凭证和登录表单提供的用户凭证在格式上存在很大的差异。基于Remember-Me的用户名/密码信息是经过特殊编码的字符串,Acegi通过RememberMeAuthenticationProvider负责对基于Cookie的用户凭证信息进行认证。所以你必须将该认证提供者添加到authenticationManager中,如④所示,注意key属性的设置,它和 代码清单 12中的key必须相同。如果保存在数据库中的密码使用了特殊编码,则你必须为RememberMeAuthenticationProvider配置特定的密码编码器,请参考代码清单 8进行配置。
删除Remember-Me的Cookie
站点如何提供了Remember-Me的功能,就必须同时提供能让用户手工删除Cookie的功能,以便用户在某些情况下,能够删除掉Cookie。Acegi提供了一个并不是很理想的实现:在退出系统时通过配置一个LogoutHandler清除Remember-Me的Cookie。
在上一节中,我们知道SecurityContextLogoutHandler是LogoutHandler的实现类,它负责在退出系统时删除HttpSession中的SecurityContext。LogoutHandler接口的另一个实现类是TokenBasedRememberMeServices(如前所述,它同时也实现了RememberMeServices接口)。你可以在LogoutFilter中添加TokenBasedRememberMeServices,以便用户退出系统时连带清除Remember-Me。
由于TokenBasedRememberMeServices已经在前面配置好了,这里仅需要简单地将其加入到LogoutFilter的LogoutHandler列表中即可,如下所示:
代码清单 15 applicationContext-acegi-security.xml:清除Remember-Me的Cookie
<bean id="logoutFilter"
class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.jsp" />
<constructor-arg>
<list>
①添加清除Remember-Me Cookie的LogoutHandler
<ref bean="rememberMeServices"/>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/j_acegi_logout" />
</bean>
…
想象一下,这种处理方式是否合理呢?可以说不合理得近乎点荒唐——用户在登录时选择启用Remember-Me功能,就是希望在退出系统后能够在Cookie中保留用户信息,方便后续系统的访问,现在居然在退出系统后就清除掉这个Cookie。也就是说,Remember-Me Cookie仅在用户登录到用户退出系统这段时间内有效,但这段时间我们根本不需要用到这个Cookie! httpSessionContextIntegrationFilter已经很好地通过HttpSession的转存实现了在不同请求之间共享Authentication的功能。
所以Acegi提供的这种设计,笔者认为只是一个使用范例,开发者必须编写自己的实现类以提供更有意义的实现。如在用户退出系统时,允许用户通过选择的方式决定是否删除Remember-Me的Cookie,或者专门提供一个清除Remember-Me Cookie的操作链接。
小结
使用Acegi,你就可以通过配置的方式完成应用程序的身份认证。这包括对密码进行加密的认证,使用Remember-Me,退出系统后清楚Session等在身份认证时常用的各项功能。用户认证是Acegi保护应用系统的第一步,因为只能获取操作用户的身份后,才能获取用户的权限,并根据用户权限进行程序安全控制。
分享到:
相关推荐
.rememberMe().rememberMeServices(rememberMeServices()) .key("key") // 同上面的key .rememberMeParameter("remember-me") // 前端提交的参数名 .tokenRepository(persistentTokenRepository()) ....
通过Vaadin实施“记住我” 登录表单最常见的功能之一是“记住我”功能,即使HTTP会话期满后,该功能也允许用户从特定计算机上自动登录。 此示例应用程序显示了如何使用Vaadin实现“记住我”功能。 您可以在阅读完整...
4. **自动登录(Remember-Me服务)**: 自动登录功能是Spring Security的"Remember-Me"服务提供的。它通过在用户登录时生成一个长期有效的令牌,存储在用户的浏览器Cookie中。当用户下次访问时,如果Cookie存在,...
4. **TicketRegistry**:这个组件管理所有的票据,包括RememberMe票据。它负责存储和检索票据,以便在需要时进行验证。 5. **Configuration**:配置RememberMe服务,通常在`cas-server-support-remember-me`模块的...
在Demo中,Ehcache被用作缓存系统来存储RememberMe数据,但其默认配置已被修改为3秒的超时,这可以根据实际需求进行调整。 3. **Cookie与Token**:RememberMe功能通常通过Cookie在客户端存储一个唯一的标识符,这个...
4. 测试认证和授权流程,确保用户能正确登录,并在下次访问时自动记住登录状态。 总结,Spring Security 3.2提供了对LDAP的强大支持,结合Remember-me功能,可以构建出高效且安全的企业级认证授权系统。理解并熟练...
而Acegi Security的"rememberMe"服务就实现了这一功能,为用户提供便捷的登录体验。 在Acegi Security中,"Remember Me"功能主要通过RememberMeServices接口实现,该接口定义了处理Remember Me令牌的方法。通常,这...
本文将深入探讨如何在Spring Security中配置和使用`rememberMe`自动登录,以及其背后的持久化令牌方案。 ### 一、`rememberMe`基础配置 在Spring Security中,启用`rememberMe`功能非常直观。首先,你需要在`...
本文将深入探讨Acegi Security中的"rememberMe"功能以及匿名登录的实现机制。 "Remember Me"功能在许多Web应用中非常常见,它允许用户在登录后选择“记住我”,以便在未来的会话中自动登录,而无需每次都输入用户名...
- 使用`http.formLogin()`来配置表单登录,并通过`http.rememberMe()`来启用Remember-Me功能。 - 配置Remember-Me时,需要提供Token的持久化方式,例如数据库连接和表结构。 4. **Cookie的安全性**: - Cookie应...
.rememberMe() .tokenValiditySeconds(1209600) .tokenRepository(tokenRepository()); } ``` 五、获取登录用户信息 在 Spring Security 中,可以使用 Authentication 对象获取登录用户信息: ```java @...
当用户下次访问时,如果没有提供用户名和密码,Remember me服务会检查这个令牌,并根据其内容恢复用户的身份,从而实现自动登录。 2. 后台存储机制:Remember me的令牌需要在服务器端进行验证和管理,这就涉及到了...
Symfony框架提供了一种称为“Remember Me”(记住我)的功能,允许用户选择自动登录,从而提高用户体验。本文将详细介绍如何在Symfony 5项目中实现Remember Me功能,并解释其工作原理及相关配置。 #### 二、...
如果有,就自动填充到登录界面的输入框,并尝试进行自动登录: ```java SharedPreferences preferences = getSharedPreferences("LoginData", MODE_PRIVATE); String savedUsername = preferences.getString(...
`remember-me` 功能允许用户在退出登录后,一段时间内再次访问时自动登录。为此,需要在数据库中创建一个名为 `persistent_logins` 的表来存储 remember-me 信息。同时,在 `configure(HttpSecurity http)` 中配置 ...
http.rememberMe().tokenRepository(tokenRepository).and().// other configurations... } } ``` 通过这种方式,即使服务器重启,Remember-Me的功能依然能够正常工作,因为Cookie的值在数据库中有备份。 总结来...
当用户再次访问系统时,系统将读取 Cookie 中的 Token,并根据 Token 从数据库中获取用户信息,以便实现自动登录。 二、实现 RememberMe 功能 要实现 RememberMe 功能,需要在登录表单中添加一个 Checkbox,名称为...
之后的每次请求,浏览器都会自动带上"RememberMe"cookie,服务器根据该cookie判断用户是否已登录。 4. **服务器端会话管理** "RememberMe"不仅涉及cookie,还与服务器端的会话管理紧密相关。服务器可能使用Session...
Remember-Me 功能可以让用户在登录后,系统记住用户的登录信息,下次登录时自动登录。前端可以通过 checkbox 来实现 Remember-Me 功能。 Spring Security 是一个功能强大且灵活的安全框架,提供了许多功能来保护...
【acegi rememberMe】是基于Acegi Security框架的一个特性,主要关注的是用户认证过程中的“记住我”功能。Acegi Security是Spring Security的前身,它为Spring应用提供了全面的安全管理框架,包括身份验证、授权、...