1. 程式人生 > >Spring Seurity系列(七)記住使用者名稱登入功能

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:

說明:本系列部落格是記錄慕課網中的教程的學習,以便我自己複習回憶。文中涉及的一些細節問題請參考慕課網中相關視訊。