UserDetails

UserDetailsUserDetailsService 返回。`DaoAuthenticationProvider` 驗證 `UserDetails` 並返回一個 Authentication 物件,該物件的 Principal 即為配置的 `UserDetailsService` 返回的 `UserDetails`。

憑證管理

強烈建議在儲存使用者憑證的類中實現 CredentialsContainer 介面,例如擴充套件或實現 UserDetails 的類,尤其是在未快取使用者詳情的應用中。這種做法透過確保敏感資料(例如密碼)不會在記憶體中保留超出必要的時間來增強安全性。

如果使用者詳情被快取,請考慮建立一個不包含憑證的 UserDetails 副本,並在自定義 AuthenticationProvider 的響應中返回該副本,而不是原始物件。這有助於防止包含憑證的快取例項在認證過程完成後被應用的其餘部分引用。

何時實現 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 實現中符合安全最佳實踐,透過最小化敏感資料在記憶體中的生命週期,減少潛在的資料洩露風險。