我们来看看springsecurity的记住我功能是如何实现的。
一、原理图
用户第一次登录的时候认证成功,将token写入数据库,同时将token写入浏览器cookie,当下一次登录请求时,带着token去数据库查找,如果找到则带着登录信息去调用userDetailService实现登录。
二、配置记住我
@Configuration
public class BrowserConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Autowired
private IAuthenticationSuccessHandler authentication;
@Autowired
private IAuthenticationFailHandler failHandler;
@Autowired
private SecurityProperties securityProperties;
@Autowired
private DataSource dataSource;
@Autowired
private MyUserDetailService userDetailsService;
@Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
// tokenRepository.setCreateTableOnStartup(true); // 第一次启动的时候数据库生成存token 的表
return tokenRepository;
};
@Override
protected void configure(HttpSecurity http) throws Exception {
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setAuthenticationFailureHandler(failHandler); // 使用我们自定义的失败处理器
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) // 在UsernamePasswordAuthenticationFilter过滤器前面增加验证码过滤器
.formLogin()
.loginPage("/authentication/require")
.loginProcessingUrl("/authentication/form")
.successHandler(authentication)
.failureHandler(failHandler)
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository()) // 设置tokenRepository
.tokenValiditySeconds(securityProperties.getProperties().getRememberMeSeconds()) // 设置过期时间
.userDetailsService(userDetailsService) // 设置登录信息
.and()
.authorizeRequests()
.antMatchers("/authentication/require",
securityProperties.getProperties().getLoginPage(),
"/code/image" ).permitAll() // 不拦截/code/image
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
}
JdbcTokenRepositoryImpl 类中有生成存放token的sql。
三、需要注意的点
1)tokenRepository.setCreateTableOnStartup(true); 第一次启动的时候生成表,如果不是第一次启动则需要注掉,不然会报错,因为数据库中已经存在这张表了。
2)页面上记住我的name必须时remember-me,不然无法实现记住我功能。
<td colspan='2'><input name="remember-me" type="checkbox" value="true" />记住我</td>
这样就实现了记住我功能了。