Digest Authentication
本部分详细介绍了 Spring Security 如何提供 Digest Authentication,DigestAuthenticationFilter
提供了 Digest Authentication。
你不应在现代应用程序中使用摘要认证,因为它不被认为是安全的。最明显的问题是,你必须将密码存储为纯文本或加密或 MD5 格式。所有这些存储格式都被认为是不安全的。相反,你应使用单向自适应密码哈希(bCrypt、PBKDF2、SCrypt 等)来存储凭据,而摘要认证不支持此方式。
摘要身份验证尝试解决 Basic authentication 的许多弱点,具体而言,通过确保证书从不会以明文形式通过网络发送。许多 browsers support Digest Authentication。
管理 HTTP 摘要身份验证的标准由 RFC 2617 定义,它更新 RFC 2069 规定的摘要身份验证标准的早期版本。大多数用户代理都实现 RFC 2617。Spring Security 的摘要身份验证支持与 RFC 2617 中规定的 “auth” 质量保护 (qop
) 兼容,它还提供与 RFC 2069 的向后兼容性。如果您需要使用未加密的 HTTP(没有 TLS 或 HTTPS),并且希望最大程度地提高身份验证过程的安全性,摘要身份验证被视为更具吸引力的选择。但是,每个人都应该使用 HTTPS。
摘要认证的核心是一个 “nonce”。这是服务器生成的一个值。Spring Security 的随机数遵循以下格式:
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 进行 configure。(请参阅 JavaDoc 中的 {security-api-url}org/springframework/security/crypto/password/NoOpPasswordEncoder.html[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>