此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.4.1! |
摘要式身份验证
本节详细介绍了 Spring Security 如何为提供的摘要式身份验证提供支持DigestAuthenticationFilter
.
您不应在现代应用程序中使用 Digest Authentication,因为它不被认为是安全的。 最明显的问题是您必须以明文、加密或 MD5 格式存储密码。 所有这些存储格式都被视为不安全。 相反,您应该使用单向自适应密码哈希(即 bCrypt、PBKDF2、SCrypt 等)存储凭据,而摘要式身份验证不支持这种哈希值。 |
摘要式身份验证 (Digest Authentication) 尝试解决基本身份验证的许多弱点,特别是通过确保凭证永远不会以明文形式通过网络发送。 许多浏览器都支持 Digest Authentication。
管理 HTTP 摘要式身份验证的标准由 RFC 2617 定义,它更新了 RFC 2069 规定的摘要式身份验证标准的早期版本。
大多数用户代理实现 RFC 2617。
Spring Security 的摘要身份验证支持与“auth”保护质量(qop
),RFC 2617 规定,它还提供与 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
.
下面提供了使用 Java 配置摘要式身份验证的示例:
-
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>