Spring security remembers my basic principles:
When logged in, the request is sent to the filter Username Password Authentication Filter. When the filter is authenticated successfully, the RememberMeService is called and a token is generated, which is written to the browser cookie. At the same time, there is a TokenRepository inside the RememberMeService, which writes token and user information to the database. When a user visits the system again and accesses an interface, he passes through a filter of RememberMeAuthentication Filter. He reads the token in the cookie and gives it to RememberService. RememberService will use TokenRepository to check whether there are records in the database according to token. If there are records, it will take out the user name Detail Service, and then call UserilService to get it according to the user name. Get the user information and put it in the Security Context.
RememberMeAuthentication Filter authenticates the penultimate filter position in the filter chain in Spring Security. When other authentication filters fail to authenticate successfully, RememberMeAuthentication Filter is called to try authentication.
Realization:
1. Add <input type="checkbox" name="remember-me" value="true"/> to the login form, and Spring Security defines a constant in the Spring Session RememberMeServices class. The default value is remember-me.
2. According to the schematic diagram above, to configure TokenRepository, the generated token is stored in the database. This is a configuration bean, which is placed in Browser Security Config.
3. Configure in configure
4. Add automatic login time to Browser Properties to make my time configurable
// Remember my seconds configuration
private int rememberMeSeconds = 10; Live together
package com.imooc.security.browser; @Configuration //This is a configuration public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{ //Read the login page configuration for user configuration @Autowired private SecurityProperties securityProperties; //Customized Processor After Successful Logon @Autowired private AuthenticationSuccessHandler imoocAuthenticationSuccessHandler; //Processor after Custom Authentication Failure @Autowired private AuthenticationFailureHandler imoocAuthenticationFailureHandler; //data source @Autowired private DataSource dataSource; @Autowired private UserDetailsService userDetailsService; //Attention is org.springframework.security.crypto.password.PasswordEncoder @Bean public PasswordEncoder passwordencoder(){ //BCryptPasswordEncoder implements PasswordEncoder return new BCryptPasswordEncoder(); } /** * Keep in mind my Token Repository configuration and execute it after successful login * Store token in the database after successful login * @Description: Remember my Token Repository configuration * @param @return JdbcTokenRepositoryImpl * @return PersistentTokenRepository * @throws * @author lihaoyang * @date 2018 March 5th 2013 */ @Bean public PersistentTokenRepository persistentTokenRepository(){ JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl(); jdbcTokenRepository.setDataSource(dataSource); //The corresponding tables are automatically generated at startup, which can be used to JdbcTokenRepositoryImpl To execute by oneself CREATE_TABLE_SQL Script generation table jdbcTokenRepository.setCreateTableOnStartup(true); return jdbcTokenRepository; } //Version 2: Configurable login page @Override protected void configure(HttpSecurity http) throws Exception { //Verification Code Filter ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter(); //Use your own error handling in validation code filters validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenticationFailureHandler); //Configured Verification Code Filtering url validateCodeFilter.setSecurityProperties(securityProperties); validateCodeFilter.afterPropertiesSet(); //Implementing Interface Jump Form Logon Required Authentication,security=Authentication+To grant authorization //http.httpBasic() //This is the default bullet-box authentication // http //Load the validation code filter in front of the login filter .addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) //Form Authentication Related Configuration .formLogin() .loginPage("/authentication/require") //Processing User Authentication BrowserSecurityController //Login filter UsernamePasswordAuthenticationFilter Default login url yes"/login",It can be changed here. .loginProcessingUrl("/authentication/form") .successHandler(imoocAuthenticationSuccessHandler)//Custom Authentication Post Processor .failureHandler(imoocAuthenticationFailureHandler) //Processing after login failure .and() //Keep in mind my configuration .rememberMe() .tokenRepository(persistentTokenRepository())//TokenRepository,Store in database after successful login token Of .tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())//Remember my seconds .userDetailsService(userDetailsService) //Remember when I succeed, call userDetailsService Query User Information .and() //Authorization-related configuration .authorizeRequests() // /authentication/require: Processing login, securityProperties.getBrowser().getLoginPage():User Configured Login Page .antMatchers("/authentication/require", securityProperties.getBrowser().getLoginPage(),//Leave the login page but do not filter, otherwise the error will be reported. "/verifycode/image").permitAll() //Verification Code .anyRequest() //Any request .authenticated() //Need identity authentication .and() .csrf().disable() //Close csrf protect ; } }
Because we have to deal with the database, we need to inject a data source: application.properties.
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/imooc-demo
spring.datasource.username=root
spring.datasource.password=root
Start the application, access localhost:8080/user, need to log in
Log in successfully:
Database: Generate a persistent_logins table and store a data
Stop the service and start again (comment out jdbcTokenRepository.setCreateTableOnStartup(true);) Because our user login information exists in the session, after restarting the service, visit localhost:8080/user, which should be rebooted to the login page, but because I am configured to remember, I can directly access and get the interface data.
Request header:
So far, the basic rememberMe has been completed.
The complete code is in github: https://github.com/lhy1234/spring-security