摘要式身分驗證

本節詳細說明 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>