当前位置: 首页 > 工具软件 > Spring4Me > 使用案例 >

SpringSecurity中文文档—Authentication—Remember Me

刘元青
2023-12-01

Remember-me或persistent-login authentication 指的是网站能够在会话之间记住主体的身份。这通常是通过向浏览器发送cookie来实现的,在未来的会话中会检测到cookie,并导致自动登录。Spring Security为这些操作提供了必要的hooks ,并有两个具体的Memory me实现。一种使用哈希来保护基于cookie的令牌的安全性,另一种使用数据库或其他持久存储机制来存储生成的令牌。
请注意,这两种实现都需要UserDetailsService。如果您使用的身份验证提供程序不使用UserDetailsService(例如LDAP提供程序),那么除非您的应用程序上下文中也有UserDetailsService bean,否则它将无法工作。

Simple Hash-Based Token Approach

这种方法使用哈希来实现有效的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

因此,只要用户名、密码和密钥不变,Memory me令牌仅在指定的时间段内有效。值得注意的是,这有一个潜在的安全问题,即在令牌过期之前,捕获的“记住我”令牌可以从任何用户代理使用。这与digest authentication的问题相同。如果principal 知道某个token已被捕获,他们可以轻松更改密码,并立即使所有有问题的“remember-me”令牌失效。如果需要更重要的安全性,您应该使用下一节中描述的方法。或者,根本不应该使用“remember-me”服务。
如果您熟悉命名空间配置一章中讨论的主题,只需添加元素即可启用memberme身份验证:

<http>
...
<remember-me key="myAppKey"/>
</http>

通常会自动选择UserDetails服务。如果应用程序上下文中有多个,则需要指定哪个应该与user-service-ref属性一起使用,其中的值是UserDetailsService bean的名称。

Persistent Token Approach

这种方法基于本文http://jaspan.com/improved_persistent_login_cookie_best_practice经过一些小的修改(基本上,cookie中不包含用户名,以防止不必要地公开有效的登录名。本文的评论部分对此进行了讨论。)。要在名称空间配置中使用这种方法,您需要提供一个数据源引用:

<http>
...
<remember-me data-source-ref="someDataSource"/>
</http>

数据库应包含使用以下SQL创建的persistent_logins表:

create table persistent_logins (username varchar(64) not null,
								series varchar(64) primary key,
								token varchar(64) not null,
								last_used timestamp not null)

Remember-Me Interfaces and Implementations

Remember-Me与UsernamePasswordAuthenticationFilter一起使用,并通过AbstractAuthenticationProcessingFilter超类中的hooks实现。它也用于BasicAuthenticationFilter中。hooks将在适当的时间调用具体的RememberServices。界面如下所示:

Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);

void loginFail(HttpServletRequest request, HttpServletResponse response);

void loginSuccess(HttpServletRequest request, HttpServletResponse response,
	Authentication successfulAuthentication);

请参阅Javadoc,以获得关于这些方法的更全面的讨论,尽管在此阶段请注意AbstractAuthenticationProcessingFilter只调用loginFail()和loginSuccess()方法。每当SecurityContextHolder不包含身份验证时,RemembermAuthenticationFilter就会调用autoLogin()方法。因此,该接口为基础的remember me实现提供了与身份验证相关的事件的充分通知,并在web请求可能包含cookie并希望被记住时委托实现。这种设计允许任何数量的“remember me”实现策略。上面我们已经看到,Spring Security提供了两种实现。我们将依次查看这些。

TokenBasedRememberMeServices

此实现支持基于简单哈希的令牌方法中描述的更简单的方法。TokenBasedRememberMeServices生成一个RememberAuthenticationToken,由RememberAuthenticationProvider处理。此身份验证提供程序和TokenBasedMemberMeservices之间共享密钥。此外,TokenBasedMemberMeservices需要UserDetails服务,它可以从中检索用户名和密码以进行签名比较,并生成RememberAuthenticationToken以包含正确的授权。应用程序应该提供某种注销命令,如果用户请求,该命令将使cookie无效。TokenBasedMemberMeservices还实现了Spring Security的LogoutHandler接口,因此可以与LogoutFilter一起使用,自动清除cookie。
应用程序上下文中启用remember-me服务所需的bean如下:

<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>

<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>

<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>

PersistentTokenBasedRememberMeServices

此类的使用方式与TokenBasedMemberMeservices相同,但它还需要配置一个PersistentTokenRepository来存储令牌。有两种标准实现:

  • InMemoryTokenRepositoryImpl 仅用于测试
  • JdbcTokenRepositoryImpl 将token存储于数据库。.
 类似资料: