UserDetails
UserDetails
由 UserDetailsService
返回。`DaoAuthenticationProvider` 验证 `UserDetails` 并返回一个 Authentication
对象,该对象的 Principal 即为配置的 `UserDetailsService` 返回的 `UserDetails`。
凭证管理
强烈建议在存储用户凭证的类中实现 CredentialsContainer
接口,例如扩展或实现 UserDetails
的类,尤其是在未缓存用户详情的应用中。这种做法通过确保敏感数据(例如密码)不会在内存中保留超出必要的时间来增强安全性。
如果用户详情被缓存,请考虑创建一个不包含凭证的 |
何时实现 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
}
}
实现指南
-
立即擦除:凭证在不再需要后应立即擦除,通常是在认证后。
-
自动调用:确保在认证过程完成后,您的认证框架(例如
AuthenticationManager
)会自动调用eraseCredentials()
。 -
一致性:在所有应用中统一应用此实践,以防止可能导致数据泄露的安全漏洞。
超越基本接口实现
虽然 CredentialsContainer
等接口提供了凭证管理的框架,但实际实现通常取决于特定的类及其交互。
例如,DaoAuthenticationProvider
类遵循 AuthenticationProvider
的契约,在其自己的 authenticate
方法中不执行凭证擦除。相反,它依赖于 ProviderManager
(Spring Security 中 AuthenticationManager
的默认实现)在认证后处理凭证和其他敏感数据的擦除。这种分离强调了 AuthenticationProvider
不应承担凭证管理责任的原则。
将 CredentialsContainer
集成到您的 UserDetails
实现中符合安全最佳实践,通过最小化敏感数据在内存中的生命周期,减少潜在的数据泄露风险。