Spring Seurity系列(七)記住使用者名稱登入功能
阿新 • • 發佈:2019-02-03
記住我功能的基本原理
使用者傳送請求到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:
說明:本系列部落格是記錄慕課網中的教程的學習,以便我自己複習回憶。文中涉及的一些細節問題請參考慕課網中相關視訊。