前言
我們採用的是持久化令牌方案,其中最核心的是series和token兩個值。
1.創建一張存儲自動登錄信息的表
CREATE TABLE `persistent_logins` (
`username` varchar(64) NOT NULL,
`series` varchar(64) NOT NULL,
`token` varchar(64) NOT NULL,
`last_used` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存儲自動登錄的表';
2.webSecurityConfig類按照如下配置
package com.demo.springsecuritydemo.config;
import com.demo.springsecuritydemo.handler.MyAuthenticationFailureHandler;
import com.demo.springsecuritydemo.handler.MyAuthenticationSuccessHandler;
import com.demo.springsecuritydemo.service.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import javax.sql.DataSource;
/**
* 自定登錄與註銷登錄配置
*
* @author suvue
* @date 2020/5/3
*/
@EnableWebSecurity
public class WebSecurityConfig2 extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
//爲tokenRepository指定一個數據源
final JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
http.authorizeRequests()
.antMatchers("/admin/api/**").hasRole("ADMIN")
.antMatchers("/user/api/**").hasRole("USER")
//開放captcha.jpg的訪問權限
.antMatchers("/app/api/**", "/captcha.jpg").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin()
.successHandler(new MyAuthenticationSuccessHandler())
.failureHandler(new MyAuthenticationFailureHandler())
.permitAll()
.and()
//增加自定登錄功能,默認爲簡單散列加密
.rememberMe().userDetailsService(myUserDetailsService)
//設置key的作用是每次重啓服務器後,自動登錄仍然會生效,但是對用戶來說風險加大
//.key("rememberMe")
//指定一個tokenRepository,用於存取Series和token等用戶驗證信息
.tokenRepository(jdbcTokenRepository)
.and()
//指定接受註銷請求的路由
.logout().logoutUrl("/myLogout")
//註銷成功,跳轉到該路徑
.logoutSuccessUrl("/login")
//使該用戶的httpSession失效
.invalidateHttpSession(true)
;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//使用我們自定義的數據庫模型
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder);
}
}
注意:MyAuthenticationSuccessHandler和MyAuthenticationFailureHandler是返回成功或者失敗的json數據的,常用於前後端分離。
3.打開網頁自行測試即可
會看到登錄框中有一個類似rememberMe的複選框。