摘要认证
本节详细介绍了 Spring Security 如何为 摘要认证 提供支持,该功能由 DigestAuthenticationFilter 提供。
注意
在现代应用中,你不应使用摘要认证(Digest Authentication),因为它被认为不够安全。最明显的问题是,你必须以明文、加密或 MD5 格式存储密码。所有这些存储方式都被认为是不安全的。相反,你应该使用单向自适应密码哈希(如 bCrypt、PBKDF2、SCrypt 等)来存储凭据,而摘要认证不支持这些方式。
摘要认证(Digest Authentication)旨在解决基础认证的诸多弱点,特别是确保凭证永远不会以明文形式通过网络传输。许多浏览器都支持摘要认证。
摘要认证的核心是“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>