Spring Seurity系列(七)记住用户名登录功能

记住我功能的基本原理 

 用户发送请求到UsernamePasswordAuthenticationFilter,当用户认证成功以后,会调一个RemeberMeService这样一个服务。这个服务里面有一个TokenRepository,会生成一个Token,将这个Token写入到浏览器的Cookie里面,同时TokenRepository把生成的Token写入到数据库里面(还有用户名)。过了一天用户来访问系统 就不需要登陆了,直接访问某一个受保护的服务,这个请求在经过过滤器链的时候会经过RemberMeAuenticationFilter(读取Cookie中的Token)给RemberMeService,RemberMeService会根据Token到数据库里面去查。如果有记录,就会把Username用户名取出来,取出来之后会调用UserDetailsService,获取用户信息,然后把用户信息放入到SecurityContext里面。

RemberMeAuenticationFilter位置:

实现:

页面:

安全配置类:

/**
 * 安全配置类
 * @author zhailiang
 *
 */
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private SecurityProperties securityProperties;
	
	@Autowired
	private AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;
	
	@Autowired
	private AuthenticationFailureHandler imoocAuthenctiationFailureHandler;
	
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	//记住我的主要操作配置
	@Autowired
	private DataSource dataSource;
	
	@Autowired
	private UserDetailsService userDetailsService;
	
	//记住我的主要操作配置
	@Bean
	public PersistentTokenRepository persistentTokenRepository() {
		JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
		tokenRepository.setDataSource(dataSource);
//		tokenRepository.setCreateTableOnStartup(true);
		return tokenRepository;
	}
	
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		
		//验证码的配置
		ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
		validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenctiationFailureHandler);
		validateCodeFilter.setSecurityProperties(securityProperties);
		validateCodeFilter.afterPropertiesSet();
		
		//将验证码的过滤器放在登录验证过滤器之前
		http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
			.formLogin()
			.loginPage("/authentication/require")
			.loginProcessingUrl("/authentication/form")
			.successHandler(imoocAuthenticationSuccessHandler)//登录成功的处理
			.failureHandler(imoocAuthenctiationFailureHandler)//登录失败的处理
			.and()
			.rememberMe()//记住我的操作
				.tokenRepository(persistentTokenRepository())
				.tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())
				.userDetailsService(userDetailsService)
			.and()
			.authorizeRequests()
			.antMatchers("/authentication/require",
					securityProperties.getBrowser().getLoginPage(),
					"/code/image").permitAll()
			.anyRequest()
			.authenticated()
			.and()
			.csrf().disable();
	}

}

 BrowserProperties:

public class BrowserProperties {
	
	private String loginPage = "/imooc-signIn.html";
	
	private LoginType loginType = LoginType.JSON;
	
	//记住密码的时间
	private int rememberMeSeconds = 3600;

	public String getLoginPage() {
		return loginPage;
	}

	public void setLoginPage(String loginPage) {
		this.loginPage = loginPage;
	}

	public LoginType getLoginType() {
		return loginType;
	}

	public void setLoginType(LoginType loginType) {
		this.loginType = loginType;
	}

	public int getRememberMeSeconds() {
		return rememberMeSeconds;
	}

	public void setRememberMeSeconds(int rememberMeSeconds) {
		this.rememberMeSeconds = rememberMeSeconds;
	}
}

JdbcTokenRepositoryImpl:

AbstractAuthenticationProcessingFilter:

AbstractRememberMeServices:

PersistentTokenBasedRememberMeServices:

RememberMeAuthenticationFilter:

猜你喜欢

转载自blog.csdn.net/newhanzhe/article/details/81201649
今日推荐