RememberMeAuthenticationFilter
RememberMeAuthenticationFilter
RememberMeAuthenticationFilter
是用于处理 "记住我" 功能的过滤器。这个功能允许用户在成功登录后,即使关闭浏览器或在一定时间内没有活动,依然保持登录状态,从而避免频繁要求用户重新输入用户名和密码。
RememberMeAuthenticationFilter
主要负责从请求中提取 "记住我" 相关的认证信息(通常是一个由浏览器发送的 remember-me
cookie),并基于这个信息恢复用户的身份认证信息。
1、功能简介
记住我功能允许用户在登录后选择是否在浏览器中保留登录状态。通常,这通过一个 remember-me
cookie 来实现。当用户再次访问网站时,如果浏览器中存在有效的 remember-me
cookie,Spring Security 会自动恢复用户的登录状态,而无需再次进行身份验证。
- 用户在登录时选择 “记住我” 选项。
- 系统将会生成一个持久的
remember-me
cookie,通常包含加密的信息,用于标识用户。 - 当用户关闭浏览器并重新打开时,如果
remember-me
cookie 依然有效,Spring Security 会通过RememberMeAuthenticationFilter
来恢复用户的认证状态。
RememberMeAuthenticationFilter
的工作流程
2、RememberMeAuthenticationFilter
主要有以下几个步骤:
- 请求到达:当用户请求一个受保护资源时,
RememberMeAuthenticationFilter
会检查请求中是否存在remember-me
cookie(通常是名为remember-me
或自定义名称的 cookie)。 - 验证
remember-me
cookie:如果请求中存在remember-me
cookie,RememberMeAuthenticationFilter
会提取该 cookie 并验证其内容。验证的过程通常包括:- 解码并验证 cookie 中的加密信息。
- 检查 cookie 是否有效(例如,检查过期时间、签名是否匹配等)。
- 恢复认证信息:如果
remember-me
cookie 有效,RememberMeAuthenticationFilter
会将从 cookie 中提取的认证信息(通常是用户的 ID 和一些验证信息)转换成一个Authentication
对象,并将其存储到SecurityContextHolder
中。 - 继续处理请求:一旦用户的身份信息被恢复并存储在
SecurityContextHolder
中,Spring Security 将继续执行剩余的过滤器和请求处理流程,用户就能够访问受保护的资源。 - 认证失败:如果
remember-me
cookie 无效或无效,过滤器会允许请求继续,且不会干预后续的认证流程。用户会被重定向到登录页面或者其他错误页面,取决于配置。
3、如何启用和配置 Remember Me 功能
在 Spring Security 中,启用和配置 “记住我” 功能通常涉及以下几个步骤:
- 启用
RememberMeAuthenticationFilter
:- 默认情况下,Spring Security 不会启用
RememberMeAuthenticationFilter
,你需要通过HttpSecurity
配置来启用这个功能。
- 默认情况下,Spring Security 不会启用
- 配置
RememberMeAuthenticationFilter
:- 你需要配置一个
RememberMeServices
,它会处理 cookie 的生成和验证。
- 你需要配置一个
3.1、配置示例
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated() // 配置所有请求都需要认证
.and()
.formLogin() // 启用表单登录
.permitAll()
.and()
.rememberMe() // 启用 "记住我" 功能
.key("uniqueAndSecret") // 用于签名 cookie 的密钥,确保安全性
.tokenValiditySeconds(86400) // cookie 有效期,单位为秒,这里是 24 小时
.and()
.httpBasic().disable(); // 禁用 HTTP Basic 认证
return http.build();
}
}
3.2、配置详解
rememberMe()
:启用 "记住我" 功能。key()
:设置一个用于签名 cookie 的唯一密钥,这个密钥可以防止 cookie 被伪造。tokenValiditySeconds()
:设置remember-me
cookie 的有效期,单位为秒。默认为 14 天(1209600 秒)。例如,86400
是一天的有效期。
SecurityFilterChain
定义了 Spring Security 的过滤器链。在这个例子中,rememberMe()
的配置将会启用RememberMeAuthenticationFilter
,该过滤器会自动拦截包含有效remember-me
cookie 的请求。
RememberMeServices
4、自定义 Spring Security 提供了 RememberMeServices
接口,它用于管理 remember-me
cookie 的生成和验证。默认情况下,Spring Security 提供了一个基于 InMemoryRememberMeServices
的实现,它会将 remember-me
信息存储在内存中。
如果你希望使用数据库或其他存储机制来持久化用户的 remember-me
信息,你可以自定义 RememberMeServices
。
例如,可以自定义一个 JdbcTokenRepositoryImpl
:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository()) // 自定义 token 存储库
.tokenValiditySeconds(86400)
.and()
.httpBasic().disable();
return http.build();
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource()); // 配置数据源
return tokenRepository;
}
@Bean
public DataSource dataSource() {
// 配置数据源
return new HikariDataSource(); // 假设使用 HikariCP 数据源
}
}
在这个例子中,JdbcTokenRepositoryImpl
被用来将 remember-me
token 存储在数据库中。这对于需要跨会话持久化的应用程序非常有用。
RememberMeAuthenticationFilter
的执行顺序
5、RememberMeAuthenticationFilter
在 Spring Security 过滤器链中的位置通常较为靠前,通常位于 UsernamePasswordAuthenticationFilter
之前。这意味着在用户名密码认证之前,Spring Security 会先检查是否存在有效的 remember-me
cookie,如果存在并且有效,它将恢复用户的身份认证信息。
过滤器链顺序如下:
SecurityContextPersistenceFilter
:保证安全上下文的存在。RememberMeAuthenticationFilter
:处理 "记住我" 功能。UsernamePasswordAuthenticationFilter
:处理标准表单登录认证。- 其他过滤器(如
ExceptionTranslationFilter
、FilterSecurityInterceptor
等)负责处理授权等任务。
6、总结
RememberMeAuthenticationFilter
是 Spring Security 中用于实现 “记住我” 功能的核心过滤器。它通过从浏览器请求中提取remember-me
cookie,恢复用户的认证状态,避免用户频繁登录。- 你可以通过 Spring Security 配置启用和定制 "记住我" 功能,支持自定义 cookie 的有效期、签名密钥以及持久化存储方案。
RememberMeAuthenticationFilter
通常与UsernamePasswordAuthenticationFilter
配合工作,确保用户的认证信息在浏览器关闭后也能够保持有效。
通过 RememberMeAuthenticationFilter
,Spring Security 提供了一个简便而安全的方式来实现长时间的用户登录保持,提升用户体验。