javascript
SpringBoot集成Spring Security —— 第二章自动登录
文章目錄
- 一、修改login.html
- 二、兩種實現(xiàn)方式
- 2.1 Cookie 存儲
- 2.2 數(shù)據(jù)庫存儲
- 2.2.1 基本原理
- 2.2.2 代碼實現(xiàn)
- 三、運行程序
在上一章:SpringBoot集成Spring Security(1)——第一章,我們實現(xiàn)了入門程序,本篇為該程序加上自動登錄的功能。
代碼地址:https://github.com/FadeHub/spring-boot-learn/tree/master/spring-boot-security-2
一、修改login.html
在登陸頁添加自動登錄的選項,注意自動登錄字段的 name 必須是 remember-me :
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>登陸</title> </head> <body> <h1>登陸</h1> <form method="post" action="/login"><div>用戶名:<input type="text" name="username"></div><div>密碼:<input type="password" name="password"></div><div><label><input type="checkbox" name="remember-me"/>自動登錄</label><button type="submit">立即登陸</button></div> </form> </body> </html>二、兩種實現(xiàn)方式
2.1 Cookie 存儲
這種方式十分簡單,只要在 WebSecurityConfig 中的 configure() 方法添加一個 rememberMe() 即可,如下所示:
protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login")// 設(shè)置登陸成功頁.defaultSuccessUrl("/").permitAll().and()// 自定義登陸用戶名和密碼參數(shù),默認(rèn)為username和password// .usernameParameter("username")// .passwordParameter("password").logout().permitAll()//基于內(nèi)存自動登錄.and().rememberMe();http.csrf().disable();}當(dāng)我們登陸時勾選自動登錄時,會自動在 Cookie 中保存一個名為 remember-me 的cookie,默認(rèn)有效期為2周,其值是一個加密字符串:
2.2 數(shù)據(jù)庫存儲
使用 Cookie 存儲雖然很方便,但是大家都知道 Cookie 畢竟是保存在客戶端的,而且 Cookie 的值還與用戶名、密碼這些敏感數(shù)據(jù)相關(guān),雖然加密了,但是將敏感信息存在客戶端,畢竟不太安全。
Spring security 還提供了另一種相對更安全的實現(xiàn)機制:在客戶端的 Cookie 中,僅保存一個無意義的加密串(與用戶名、密碼等敏感數(shù)據(jù)無關(guān)),然后在數(shù)據(jù)庫中保存該加密串-用戶信息的對應(yīng)關(guān)系,自動登錄時,用 Cookie 中的加密串,到數(shù)據(jù)庫中驗證,如果通過,自動登錄才算通過。
2.2.1 基本原理
當(dāng)瀏覽器發(fā)起表單登錄請求時,當(dāng)通過 UsernamePasswordAuthenticationFilter 認(rèn)證成功后,會經(jīng)過 RememberMeService,在其中有個 TokenRepository,它會生成一個 token,首先將 token 寫入到瀏覽器的 Cookie 中,然后將 token、認(rèn)證成功的用戶名寫入到數(shù)據(jù)庫中。
當(dāng)瀏覽器下次請求時,會經(jīng)過 RememberMeAuthenticationFilter,它會讀取 Cookie 中的 token,交給 RememberMeService 從數(shù)據(jù)庫中查詢記錄。如果存在記錄,會讀取用戶名并去調(diào)用 UserDetailsService,獲取用戶信息,并將用戶信息放入Spring Security 中,實現(xiàn)自動登陸。
RememberMeAuthenticationFilter 在整個過濾器鏈中是比較靠后的位置,也就是說在傳統(tǒng)登錄方式都無法登錄的情況下才會使用自動登陸。
2.2.2 代碼實現(xiàn)
首先需要創(chuàng)建一張表來存儲 token 信息:
CREATE TABLE `persistent_logins` (`username` varchar(64) NOT NULL,`series` varchar(64) NOT NULL,`token` varchar(64) NOT NULL,`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`series`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;在 WebSecurityConfig 中注入 dataSource ,創(chuàng)建一個 PersistentTokenRepository 的Bean:
@Autowired private DataSource dataSource;@Beanpublic PersistentTokenRepository persistentTokenRepository(){JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();tokenRepository.setDataSource(dataSource);// 如果token表不存在,使用下面語句可以初始化該表;若存在,請注釋掉這條語句,否則會報錯。 // tokenRepository.setCreateTableOnStartup(true);return tokenRepository;}在 config() 中按如下所示配置自動登陸:
@Override protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()// 如果有允許匿名的url,填在下面 // .antMatchers().permitAll().anyRequest().authenticated().and()// 設(shè)置登陸頁.formLogin().loginPage("/login")// 設(shè)置登陸成功頁.defaultSuccessUrl("/").permitAll()// 自定義登陸用戶名和密碼參數(shù),默認(rèn)為username和password // .usernameParameter("username") // .passwordParameter("password").and().logout().permitAll()// 自動登錄.and().rememberMe().tokenRepository(persistentTokenRepository())// 有效時間:單位s.tokenValiditySeconds(60).userDetailsService(userDetailsService);// 關(guān)閉CSRF跨域http.csrf().disable(); }三、運行程序
勾選自動登錄后,Cookie 和數(shù)據(jù)庫中均存儲了 token 信息:
總結(jié)
以上是生活随笔為你收集整理的SpringBoot集成Spring Security —— 第二章自动登录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring boot 整合securi
- 下一篇: SpringBoot整合Spring S