UserDetails
UserDetails 由 UserDetailsService 返回。 DaoAuthenticationProvider 验证 UserDetails,然后返回一个 Authentication,其主体是配置的 UserDetailsService 返回的 UserDetails。
凭证管理
强烈建议在存储用户凭证的类中(例如继承或实现 UserDetails 的类)实现 CredentialsContainer 接口,尤其是在不缓存用户详细信息的应用程序中。这种做法通过确保敏感数据(如密码)不会在内存中保留超过必要的时间来增强安全性。
|
在缓存用户详细信息的情况下,可以考虑创建 |
何时实现 CredentialsContainer
不使用 UserDetails 缓存机制的应用程序应特别考虑实现 CredentialsContainer。这种方法有助于降低敏感信息在内存中保留的风险,这些信息可能容易受到内存转储等攻击向量的攻击。
public class MyUserDetails implements UserDetails, CredentialsContainer {
private String username;
private String password;
// UserDetails implementation...
@Override
public void eraseCredentials() {
this.password = null; // Securely dereference the password field
}
}
实施指南
-
立即擦除:凭证应在不再需要时(通常在身份验证后)立即擦除。
-
自动调用:确保
eraseCredentials()在身份验证过程完成后由您的身份验证框架(例如AuthenticationManager)自动调用。 -
一致性:在所有应用程序中统一应用此做法,以防止可能导致数据泄露的安全漏洞。
超越基本接口实现
虽然 CredentialsContainer 等接口提供了凭证管理的框架,但实际实现通常取决于特定的类及其交互。
例如,DaoAuthenticationProvider 类,遵守 AuthenticationProvider 的契约,不会在其自身的 authenticate 方法中执行凭证擦除。相反,它依赖于 ProviderManager(Spring Security 中 AuthenticationManager 的默认实现)来处理身份验证后的凭证和其他敏感数据的擦除。这种分离强调了 AuthenticationProvider 不应承担凭证管理职责的原则。
将 CredentialsContainer 纳入您的 UserDetails 实现与安全最佳实践保持一致,通过最大限度地缩短敏感数据在内存中的生命周期,降低了数据泄露的潜在风险。