第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Spring Security Spring Security 實(shí)現(xiàn)記住我功能

實(shí)現(xiàn)記住我功能

1. 前言

「記住我」這一功能多出現(xiàn)在互聯(lián)網(wǎng)應(yīng)用中,其目的是為了減少用戶的認(rèn)證次數(shù)和訪問門檻。在一般的內(nèi)網(wǎng)應(yīng)用、或者是安全性要求較高的管理后臺(tái)中出現(xiàn)使用頻度較低。

「記住我 Remember-me」也稱為「持續(xù)登錄 Persistent-login」, 主要用到了 Cookies 和 Token 技術(shù),本節(jié)重點(diǎn)討論如何通過 Spring Security 配合出「記住我」的自動(dòng)認(rèn)證功能。

2. 記住我原理

圖片描述

「記住我」的核心思路是:將認(rèn)證狀態(tài)以安全的方式保存在客戶端

「記住我」需要通過向?yàn)g覽器設(shè)置 Cookies 信息,這個(gè) Cookies 信息未來會(huì)用于建立會(huì)話連接,并且提供自動(dòng)登錄的能力。

「記住我」的基本流程為:

  1. 用戶通過瀏覽器登錄成功后,服務(wù)端生成一個(gè)可以持久化使用的 Token,并返回給瀏覽器;
  2. 瀏覽器端將該 Token 保存到 Cookies 中;
  3. 當(dāng)用戶離開應(yīng)用系統(tǒng),并再次返回,此時(shí)服務(wù)端由于沒有了該用戶的登錄會(huì)話,所以要求用戶再次登錄;
  4. 瀏覽器檢查 Cookies 中是否包含「記住我」的 Token,如有,將其發(fā)送給服務(wù)端;
  5. 服務(wù)端驗(yàn)證 Token,如果成功,直接返回登錄成功的結(jié)果。

3. 集成步驟

3.1 「記住我」Token 的存儲(chǔ)方式

通過前面描述我們看到,要實(shí)現(xiàn)「記住我」功能,關(guān)鍵在于如何安全的保護(hù)好用戶的認(rèn)證信息 Token。Spring Security 提供了兩種「記住我」的實(shí)現(xiàn)方式:

  1. 使用 Hash 算法加密認(rèn)證信息形成 Token,并將其保存在客戶端中;

  2. 將認(rèn)證信息保存在數(shù)據(jù)庫中,并將查詢條件保存在客戶端中。

3.1.1 基于 Hash 的方式

基于 Hash 的方式是一種相對簡單的集成方式。這種方式利用 Hash 的特性,將「記住我」信息進(jìn)行存檔。每當(dāng)用戶認(rèn)證通過,服務(wù)端便生成一條 Hash 記錄,并發(fā)送給客戶端瀏覽器,其中內(nèi)容包括「用戶名」、「Token 過期時(shí)間」、「密碼」、「簽名秘鑰」。

發(fā)送的具體內(nèi)容為:

base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))

username:          根據(jù) UserDetailsService 配置得到用戶名信息。
password:          認(rèn)證密碼,確保 UserDetailsService 中可以匹配到目標(biāo)用戶。
expirationTime:    「記住我」Roken 的有效期,精確到毫秒。
key:               用于給 Token 簽名的密鑰信息,防止該 Token 被篡改。

發(fā)送出的 Token 只有到用戶下次需要登錄時(shí)才會(huì)被使用到,這期間,需要確保用戶名、密碼、密鑰等信息不被改變。還需要注意的是,「記住我」Token 在過期之前,可以在任何地方使用,因此其安全性上有一定的問題,如果使用數(shù)字認(rèn)證一樣。當(dāng)用戶認(rèn)為自己的 Token 不在安全時(shí),最好的辦法是立刻改變自己的認(rèn)證密碼,并且使全部的「記住我」Token 失效。

啟動(dòng)「記住我」功能僅需要一行配置,具體方式為:

<http>
...
<remember-me key="簽名密鑰"/>
</http>

當(dāng)有多個(gè) UserDetailsService 實(shí)例時(shí),可以通過 user-service-ref 屬性指定唯一實(shí)例。

3.1.2 基于存儲(chǔ)的方式

使用數(shù)據(jù)庫作為 Token 存儲(chǔ)方式,需要在 <remember-me> 配置中增加 data-source-ref 屬性,配置方式如下:

<http>
...
<remember-me data-source-ref="數(shù)據(jù)源實(shí)例"/>
</http>

所用到的數(shù)據(jù)源需要包含 persistent_logins 數(shù)據(jù)表,其結(jié)構(gòu)如下:

create table persistent_logins (username varchar(64) not null,
                                series varchar(64) primary key,
                                token varchar(64) not null,
                                last_used timestamp not null)

3.2 「記住我」相關(guān)接口及其實(shí)現(xiàn)

「記住我」需要配合「用戶名密碼認(rèn)證過濾器」一起使用,觸發(fā) RememberMeServices 實(shí)例實(shí)現(xiàn)其效果?!赣涀∥摇菇涌谥杏腥齻€(gè)主要方法,第一個(gè)名為 autoLogin 用于自動(dòng)登錄審核,另外兩個(gè)是 loginFailloginSuccess 分別在認(rèn)證失敗或成功時(shí)觸發(fā)。

具體表現(xiàn)形式為:

// 自動(dòng)認(rèn)證
Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);

自動(dòng)認(rèn)證方法,在「記住我」功能啟用后,同時(shí)當(dāng)前上下文中找不到用戶信息時(shí)觸發(fā),我們需要根據(jù)不同的 Token 策略,實(shí)現(xiàn)「記住我」的判斷邏輯。

// 登錄失敗時(shí)觸發(fā)
void loginFail(HttpServletRequest request, HttpServletResponse response);
// 登錄成功時(shí)觸發(fā)
void loginSuccess(HttpServletRequest request, HttpServletResponse response,
    Authentication successfulAuthentication);

如前文所述,「記住我」有兩種 Token 策略,對應(yīng)了兩種實(shí)現(xiàn)方法。

3.2.1 基于 Hash 方式的實(shí)現(xiàn)

先上代碼:

<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>

<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>

<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>

基于 Hash 的方式需要配置三個(gè)核心 Bean 對象,分別是「過濾器」、「記住我處理服務(wù)」和「認(rèn)證管理器」。這其中 TokenBasedRememberMeServices 負(fù)責(zé)生成 Token 內(nèi)容,并交給「認(rèn)證管理器」使用。

最后,要把處理服務(wù) RememberMeServices 設(shè)置到用戶名密碼認(rèn)證過濾器 UsernamePasswordAuthenticationFilter.setRememberMeServices() 里,將記住我的認(rèn)證管理器添加到 AuthenticationManager.setProviders() 之中,將記住我過濾器添加到安全過濾鏈之中。

3.2.2 基于數(shù)據(jù)存儲(chǔ)方式的實(shí)現(xiàn)

使用數(shù)據(jù)存儲(chǔ)方式,其實(shí)現(xiàn)代碼與 Hash 方式基本相同,區(qū)別在于需要繼續(xù)配置 PersistentTokenRepository 來存取 Token,有兩個(gè)標(biāo)準(zhǔn)實(shí)現(xiàn)類:第一個(gè)是基于內(nèi)存的 InMemoryTokenRepositoryImpl,第二個(gè)是基于 JDBC 的 JdbcTokenRepositoryImpl。通常情況下,第一種用于集成測試,第二種用于生產(chǎn)環(huán)境。

4. 小結(jié)

本節(jié)我們討論了「記住我」的原理及快速集成方式:

  • 「記住我」是一種基于 Token 的認(rèn)證形式;
  • 「記住我」基于瀏覽器 Cookie 實(shí)現(xiàn),在瀏覽器中保存從服務(wù)端獲取的,用于下次認(rèn)證的 Token 內(nèi)容;
  • 「記住我」是需要和用戶名密碼認(rèn)證方式同時(shí)出現(xiàn);
  • 「記住我」有兩種 Token 策略,一種基于 Hash 值,另外一種基于數(shù)據(jù)庫持久化。

下節(jié)我們討論,當(dāng)系統(tǒng)對認(rèn)證有特殊需求且無法由 Spring Security 安全框架提供時(shí),如何實(shí)現(xiàn)使用外部方式認(rèn)證,使用 Spring Security 管理認(rèn)證結(jié)果及鑒權(quán)的方法。