摘要(Digest)认证

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

本节详细介绍了Spring Security如何为 Digest Authentication 提供支持,它提供了 DigestAuthenticationFilter

你不应该在现代应用中使用摘要认证,因为它被认为是不安全的。最明显的问题是,你必须以明文或加密或MD5格式存储你的密码。所有这些存储格式都被认为是不安全的。相反,你应该通过使用单向自适应密码散列(bCrypt, PBKDF2, SCrypt, 和其他)来存储凭证,这不被摘要认证所支持。

摘要认证试图解决 Basic authentication 的许多弱点,特别是通过确保凭证永远不会以明文形式通过网络发送。许多 浏览器支持摘要认证

管理HTTP摘要认证的标准是由 RFC 2617 定义的,它更新了 RFC 2069 规定的摘要认证标准的早期版本。大多数用户代理实施RFC 2617。Spring Security的摘要认证支持与RFC 2617规定的 “auth” 保护质量(qop)兼容,它还提供了与RFC 2069的后向兼容性。如果你需要使用未加密的HTTP(没有TLS或HTTPS),并希望最大限度地提高认证过程的安全性,那么摘要认证被认为是一个更具吸引力的选择。然而,每个人都应该使用 HTTPS

Digest认证的核心是 “nonce”。这是一个由服务器生成的值。Spring Security的nonce采用了以下格式。

Digest Syntax
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 配置 不安全的纯文本 密码存储(Password Storage)。(见Javadoc中的 NoOpPasswordEncoder 类。) 下面提供一个用Java配置Digest认证的例子。

Digest Authentication
  • Java

  • XML

@Autowired
UserDetailsService userDetailsService;

DigestAuthenticationEntryPoint entryPoint() {
	DigestAuthenticationEntryPoint result = new DigestAuthenticationEntryPoint();
	result.setRealmName("My App Realm");
	result.setKey("3028472b-da34-4501-bfd8-a355c42bdf92");
}

DigestAuthenticationFilter digestAuthenticationFilter() {
	DigestAuthenticationFilter result = new DigestAuthenticationFilter();
	result.setUserDetailsService(userDetailsService);
	result.setAuthenticationEntryPoint(entryPoint());
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	http
		// ...
		.exceptionHandling(e -> e.authenticationEntryPoint(authenticationEntryPoint()))
		.addFilterBefore(digestFilter());
	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>