SpringSecurity 记住我 rememberMe 功能
1.html 必须 name="remember-me"
<tr> <td colspan='2'><input name="remember-me" type="checkbox" value="true" />记住我</td> </tr>
2. 创建表 persistent_logins 也可以自动创建
自动创建 的表 sqlserver 下会出问题 sqlserver 建表语句
CREATE TABLE persistent_logins ( username VARCHAR (64) NOT NULL, series VARCHAR (64) PRIMARY KEY, token VARCHAR (64) NOT NULL, last_used datetime NOT NULL );
3. Config配置
package com.imooc.security.browser;
import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.ValidateCodeFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.sql.DataSource;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler imoocAuthenctiationFailureHandler;
@Bean
public PasswordEncoder passwordEncoder() {
return new SCryptPasswordEncoder();
}
@Autowired
private SecurityProperties securityProperties;
@Autowired
private DataSource dataSource;
@Autowired
private UserDetailsService userDetailsService; // MyUserDetailsService
/**
* 记住我功能
* 1. 创建PersistentTokenRepository
* 2. 设置过期时间
* 3. 获取UserDetailsService 用户登录信息
* 4. 配置rememberMe 生效
* @return
*/
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource); // 配置的dataSource
// jdbcTokenRepository.setCreateTableOnStartup(true); // 自动创建存放记住我的表,如果存在会报错
return jdbcTokenRepository;
}
@Override
public void configure(HttpSecurity http) throws Exception {
// 验证码过滤器
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenctiationFailureHandler);
validateCodeFilter.setSecurityProperties(securityProperties);
validateCodeFilter.afterPropertiesSet();
// 添加一个图片验证filter, 在UsernamePasswordAuthenticationFilter之前执行
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
// .httpBasic() // 默认方式
.formLogin() // 设置认证的登录方式 表单方式
.loginPage("/authentication/require") // 自定义登录页面
.loginProcessingUrl("/authentication/form") // 自定义表单提交的url, 默认是login
.successHandler(imoocAuthenticationSuccessHandler) // 不适用默认的认证成功处理器
.failureHandler(imoocAuthenctiationFailureHandler) // 登录失败处理器
// .failureForwardUrl("/authentication/require")
// .failureUrl("/authentication/require")
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository())
// rememberME 有效期
.tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())
.userDetailsService(userDetailsService)
.and()
.authorizeRequests() // 需要授权
// 当匹配到这个页面时,不需要授权
.antMatchers("/authentication/require", securityProperties.getBrowser().getLoginPage(),
"/code/image").permitAll()
.anyRequest() // 所有请求
.authenticated()
.and() // 关闭csrf
.csrf()
.disable();
}
}
4. UserDetailsService 实现类
package com.imooc.security.browser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class MyUserDetailsService implements UserDetailsService {
// 模拟密码加密
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 模拟用户数据库查询密码
String enPass = passwordEncoder.encode("123456");
return new User(username, enPass,
true,true,true,true,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}

浙公网安备 33010602011771号