Basic身份驗(yàn)證和Digest身份驗(yàn)證是Web應(yīng)用程序中流行的可選的身份驗(yàn)證機(jī)制。Basic身份驗(yàn)證通常用于無狀態(tài)客戶端,這些客戶端每次請求時上傳遞其憑證。在應(yīng)用程序通過基于瀏覽器的用戶界面和作為Web服務(wù)使用的情況下,將其與基于表單的身份驗(yàn)證結(jié)合使用是非常常見的。但是,Basic身份驗(yàn)證以純文本形式傳輸密碼,因此它應(yīng)該只在加密傳輸層(如https)上使用。
10.4.1?BasicAuthenticationFilter
basicauthenticationfilter負(fù)責(zé)處理HTTP頭中顯示的基本身份驗(yàn)證憑據(jù)。這可以用于驗(yàn)證由Spring遠(yuǎn)程處理協(xié)議(如Hessian和Burlap)以及普通瀏覽器用戶代理(如Firefox和Internet Explorer)發(fā)出的調(diào)用。HTTP基本身份驗(yàn)證的標(biāo)準(zhǔn)由RFC1945第11節(jié)定義,basicauthenticationfilter符合此RFC。基本身份驗(yàn)證是一種很有吸引力的身份驗(yàn)證方法,因?yàn)樗谟脩舸碇斜粡V泛部署,而且實(shí)現(xiàn)非常簡單(它只是用戶名:password的base64編碼,在HTTP頭中指定)。
配置
要實(shí)現(xiàn)HTTP Basic?身份驗(yàn)證,需要向過濾器鏈中添加一個 BasicAuthenticationFilter?。應(yīng)用程序上下文應(yīng)包含BasicAuthenticationFilter?及其所需的合作者:
<bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName" value="Name Of Your Realm"/>
</bean>
配置的 AuthenticationManager?處理每個認(rèn)證請求。如果認(rèn)證失敗,將使用配置的 AuthenticationEntryPoint?重試身份驗(yàn)證過程。通常,您將結(jié)合?BasicAuthenticationEntryPoint?使用過濾器,它返回帶有合適頭的401響應(yīng),以重試HTTPBasic 認(rèn)證。如果認(rèn)證成功,則生成的 Authentication?對象將像往常一樣放入SecurityContextholder中。
如果身份驗(yàn)證事件成功,或者由于HTTP頭不包含受支持的身份驗(yàn)證請求頭而未嘗試身份驗(yàn)證,則篩選器鏈將正常繼續(xù)。只有當(dāng)身份驗(yàn)證失敗并調(diào)用 AuthenticationEntryPoint?時,過濾器鏈才會中斷。
10.4.2?DigestAuthenticationFilter
DigestAuthenticationFilter能夠處理HTTP頭中顯示的摘要式身份驗(yàn)證憑據(jù)。摘要式身份驗(yàn)證試圖解決基本身份驗(yàn)證的許多弱點(diǎn),特別是通過確保憑證從未以明文形式跨線發(fā)送來解決。許多用戶代理支持摘要式身份驗(yàn)證,包括Mozilla Firefox和Internet Explorer。管理HTTP摘要式身份驗(yàn)證的標(biāo)準(zhǔn)由RFC2617定義,它更新了RFC2069規(guī)定的摘要式身份驗(yàn)證標(biāo)準(zhǔn)的早期版本。大多數(shù)用戶代理實(shí)現(xiàn)RFC2617。Spring Security的DigestAuthenticationFilter與RFC2617規(guī)定的“認(rèn)證”保護(hù)質(zhì)量(QOP)兼容,后者還提供了與RFC2069的向后兼容性。如果您需要使用未加密的HTTP(即沒有TLS/HTTPS),并且希望最大限度地提高身份驗(yàn)證過程的安全性,那么摘要式身份驗(yàn)證是一個更具吸引力的選項(xiàng)。事實(shí)上,摘要式身份驗(yàn)證是WebDAV協(xié)議的強(qiáng)制性要求,如RFC2518第17.1節(jié)所述。
您不應(yīng)該在現(xiàn)代應(yīng)用程序中使用Digest,因?yàn)樗徽J(rèn)為是不安全的。最明顯的問題是,必須以明文、加密或MD5格式存儲密碼。所有這些存儲格式都被認(rèn)為是不安全的。相反,您應(yīng)該使用單向自適應(yīng)密碼散列(即bcrypt、pbkdf2、scrypt等)。
摘要式身份驗(yàn)證的核心是“nonce”。這是服務(wù)器生成的值。Spring Security的nonce采用以下格式:
base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))
expirationTime:? The date and time when the nonce expires, expressed in milliseconds
key:? ? ? ? ? ? ? A private key to prevent modification of the nonce token
DigestAuthenticationEntryPoint具有一個屬性,通過指定key值用于生成nonce令牌的,以及一個用于確定到期時間的nonEvaliditySeconds屬性(默認(rèn)值300,等于5分鐘)。當(dāng)nonce有效時,通過連接各種字符串(包括用戶名、密碼、nonce、請求的uri、客戶端生成的nonce(僅用戶代理生成每個請求的隨機(jī)值)、領(lǐng)域名稱等)計(jì)算摘要,然后執(zhí)行MD5哈希。服務(wù)器和用戶代理都執(zhí)行這個摘要計(jì)算,如果它們對包含的值(如密碼)不一致,則會產(chǎn)生不同的哈希代碼。在Spring安全性實(shí)現(xiàn)中,如果服務(wù)器生成的nonce僅僅過期(但摘要在其他方面有效),DigestAuthenticationEntryPoint將發(fā)送一個“stale=true”頭。這告訴用戶代理不需要干擾用戶(因?yàn)槊艽a和用戶名等是正確的),只需使用新的nonce再試一次。
DigestAuthenticationEntryPoint的nonEvaluitySeconds參數(shù)的適當(dāng)值取決于您的應(yīng)用程序。非常安全的應(yīng)用程序應(yīng)該注意,在達(dá)到nonce中包含的過期時間之前,可以使用截獲的身份驗(yàn)證頭來模擬主體。這是選擇適當(dāng)設(shè)置時的關(guān)鍵原則,但對于非常安全的應(yīng)用程序來說,在第一個實(shí)例中不通過TLS/HTTPS運(yùn)行是不常見的。
由于摘要式身份驗(yàn)證的實(shí)現(xiàn)更加復(fù)雜,因此經(jīng)常會出現(xiàn)用戶代理問題。例如,Internet Explorer無法在同一會話中的后續(xù)請求上顯示“opaque????”令牌。因此,Spring安全過濾器將所有狀態(tài)信息封裝到“nonce”令牌中。在我們的測試中,Spring Security的實(shí)現(xiàn)與Mozilla Firefox和Internet Explorer可靠地工作,正確地處理非緊急超時等。
配置
現(xiàn)在我們回顧了這個理論,讓我們看看如何使用它。要實(shí)現(xiàn)HTTP摘要身份驗(yàn)證,需要在過濾器鏈中定義DigestAuthenticationFilter。應(yīng)用程序上下文需要定義DigestAuthenticationFilter及其所需的合作者:
<bean id="digestFilter" class=
? ? "org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
<property name="userDetailsService" ref="jdbcDaoImpl"/>
<property name="authenticationEntryPoint" ref="digestEntryPoint"/>
<property name="userCache" ref="userCache"/>
</bean>
<bean id="digestEntryPoint" class=
? ? "org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
<property name="realmName" value="Contacts Realm via Digest Authentication"/>
<property name="key" value="acegi"/>
<property name="nonceValiditySeconds" value="10"/>
</bean>
由于 DigestAuthenticationFilter 必須直接訪問用戶的明文密碼,因此需要配置的UserDetailsService。如果在DAO中使用編碼密碼,摘要式身份驗(yàn)證將不起作用。DAO合作者和用戶緩存通常直接與DAO身份驗(yàn)證提供程序共享。authenticationEntryPoint 屬性必須是 DigestAuthenticationEntryPoint,以便 digestauthenticationFilter 可以為digest計(jì)算獲取正確的 realmName?和?key。
與 BasicAuthenticationFilter?類似,如果驗(yàn)證成功,則將向 SecurityContextHolder 中放置認(rèn)證請求令牌。如果身份驗(yàn)證事件成功,或者由于HTTP頭不包含摘要式身份驗(yàn)證請求而未嘗試身份驗(yàn)證,則篩選器鏈將正常繼續(xù)。如前一段所述,只有當(dāng)身份驗(yàn)證失敗并調(diào)用authenticationEntryPoint時,過濾器鏈才會中斷。
摘要式身份驗(yàn)證的RFC提供了一系列附加功能,以進(jìn)一步提高安全性。例如,可以根據(jù)每個請求更改nonce。盡管如此,Spring Security?實(shí)現(xiàn)的目的是最小化實(shí)現(xiàn)的復(fù)雜性(以及可能出現(xiàn)的毫無疑問的用戶代理不兼容性),并避免需要存儲服務(wù)器端狀態(tài)。如果您希望更詳細(xì)地探討這些特性,請您查看RFC2617。據(jù)我們所知,Spring Security的實(shí)現(xiàn)確實(shí)符合這個RFC的最低標(biāo)準(zhǔn)。