摘要式身分驗證
本節詳細說明 Spring Security 如何提供 摘要式身分驗證 的支援,此支援由 DigestAuthenticationFilter
提供。
在現代應用程式中,您不應使用摘要式身分驗證,因為它被認為不安全。最明顯的問題是您必須以純文字或加密或 MD5 格式儲存密碼。所有這些儲存格式都被認為是不安全的。相反地,您應該使用單向自適應密碼雜湊 (bCrypt、PBKDF2、SCrypt 等) 來儲存憑證,但摘要式身分驗證不支援此方法。 |
摘要式身分驗證試圖解決 基本身分驗證 的許多弱點,特別是確保憑證永遠不會以明文形式透過網路傳輸。許多瀏覽器支援摘要式身分驗證。
規範 HTTP 摘要式身分驗證的標準由 RFC 2617 定義,它更新了 RFC 2069 規定的早期版本摘要式身分驗證標準。大多數使用者代理程式實作 RFC 2617。Spring Security 的摘要式身分驗證支援與 RFC 2617 規定的「auth」品質保護 (qop
) 相容,同時也提供與 RFC 2069 的向後相容性。如果您需要使用未加密的 HTTP (沒有 TLS 或 HTTPS) 並希望最大化身分驗證過程的安全性,則摘要式身分驗證被視為更具吸引力的選項。然而,每個人都應該使用 HTTPS。
摘要式身分驗證的核心是「nonce」。這是伺服器產生的值。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
您需要確保您使用 NoOpPasswordEncoder
設定 不安全的純文字密碼儲存。(請參閱 Javadoc 中的 NoOpPasswordEncoder
類別。)以下範例說明如何使用 Java 組態設定摘要式身分驗證
摘要式身分驗證
-
Java
-
XML
@Autowired
UserDetailsService userDetailsService;
DigestAuthenticationEntryPoint authenticationEntryPoint() {
DigestAuthenticationEntryPoint result = new DigestAuthenticationEntryPoint();
result.setRealmName("My App Realm");
result.setKey("3028472b-da34-4501-bfd8-a355c42bdf92");
return result;
}
DigestAuthenticationFilter digestAuthenticationFilter() {
DigestAuthenticationFilter result = new DigestAuthenticationFilter();
result.setUserDetailsService(userDetailsService);
result.setAuthenticationEntryPoint(authenticationEntryPoint());
return result;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.exceptionHandling(e -> e.authenticationEntryPoint(authenticationEntryPoint()))
.addFilter(digestAuthenticationFilter());
return http.build();
}
<b:bean id="digestFilter"
class="org.springframework.security.web.authentication.www.DigestAuthenticationFilter"
p:userDetailsService-ref="jdbcDaoImpl"
p:authenticationEntryPoint-ref="digestEntryPoint"
/>
<b:bean id="digestEntryPoint"
class="org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint"
p:realmName="My App Realm"
p:key="3028472b-da34-4501-bfd8-a355c42bdf92"
/>
<http>
<!-- ... -->
<custom-filter ref="userFilter" position="DIGEST_AUTH_FILTER"/>
</http>