# 摘要认证

本节提供了有关 Spring 安全性如何为[摘要认证](https://tools.ietf.org/html/rfc2617)提供支持的详细信息，`DigestAuthenticationFilter`提供了支持。

|   |在现代应用程序中不应该使用摘要身份验证，因为它不被认为是安全的。<br/>最明显的问题是，你必须以明文、加密或 MD5 格式存储密码，<br/>所有这些存储格式都被认为是不安全的。，相反，<br/>，你应该使用单向自适应密码散列（即 bcrypt、pbkdf2、scrypt 等）存储凭据，摘要身份验证不支持这种方式。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

摘要身份验证试图解决[基本身份验证](basic.html#servlet-authentication-basic)的许多缺点，特别是通过确保凭据永远不会以明文形式发送到网络上。许多[浏览器支持摘要身份验证](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Digest#Browser_compatibility)。

管理 HTTP 摘要身份验证的标准由[RFC 2617](https://tools.ietf.org/html/rfc2617)定义，该标准更新了[RFC 2069](https://tools.ietf.org/html/rfc2069)规定的摘要身份验证标准的早期版本。大多数用户代理实现 RFC2617。 Spring Security 的摘要身份验证支持与 RFC2617 规定的“auth”质量保护（）兼容，后者还提供与 RFC2069 的向后兼容性。如果你需要使用未加密的 HTTP（即没有 TLS/HTTPS）并希望最大限度地提高身份验证过程的安全性，则摘要身份验证被视为更具吸引力的选项。但是，每个人都应该使用[HTTPS](../../../features/exploits/http.html#http)。

摘要身份验证的核心是“nonce”。这是服务器生成的值。 Spring Security 的 nonce 采用以下格式：

例 1。摘要语法

```
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`来确保[configure](../../../features/authentication/password-storage.html#authentication-password-storage-configuration)不安全的纯文本[密码存储](../../../features/authentication/password-storage.html#authentication-password-storage)。下面提供了一个使用 爪哇 配置配置摘要身份验证的示例：

例 2。摘要认证

Java

```
@Autowired
UserDetailsService userDetailsService;

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

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

protected void configure(HttpSecurity http) throws Exception {
	http
		// ...
		.exceptionHandling(e -> e.authenticationEntryPoint(authenticationEntryPoint()))
		.addFilterBefore(digestFilter());
}
```

XML

```
<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>
```

[Basic](basic.html)[密码存储](storage.html)

