记住我基本原理
用户认证成功后调用RemeberMeService服务,这个服务里有一个TokenRepository,它会生成一个Token写入浏览器Cookie,同时它还会使用TokenRepository将Token和用户名写入到数据库中。
当用户再次访问系统时,过滤器链如下所示,请求会经过RememberMeAuthenticationFilter过滤器,该过滤器会读取cookie中的Token并将其交给RemeberMeService,TokenRepository会使用该Token去数据库里查是否存在,如果存在则取出用户名,去除用户名之后就会调用UserDetailsService获取用户信息,然后将用户信息放入SecurityContext里面,这样就把用户登录上去了。
实现步骤
1. 新建 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)
2. 添加数据库的相关依赖和配置
pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
3. SpringSecurityConfig配置类,为了看清楚添加了哪些信息,所以省略了其他的信息
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
// tokenRepository.setCreateTableOnStartup(true);
// create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)
return tokenRepository;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.rememberMe()
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(24*60*60) // 过期秒数
.userDetailsService(myUserService)
;
}
}
代码地址 https://github.com/923226145/SpringSecurity/tree/master/chapter6