UserDetails

UserDetails (Javadoc) UserDetailsService によって返されます。DaoAuthenticationProvider は UserDetails を検証してから、構成済みの UserDetailsService によって返された UserDetails であるプリンシパルを持つ Authentication を返します。

資格情報管理

UserDetails を継承または実装するクラスなど、ユーザー資格情報を保存するクラスに CredentialsContainer インターフェースを実装することを強くお勧めします。特に、ユーザーの詳細がキャッシュされないアプリケーションではこれが推奨されます。この方法により、パスワードなどの機密データが必要以上にメモリに保持されないようにすることで、セキュリティが強化されます。

ユーザーの詳細がキャッシュされている場合は、資格情報を含まない 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 実装に組み込むと、セキュリティのベストプラクティスに準拠し、メモリ内の機密データの寿命を最小限に抑えることで、データ侵害の潜在的なリスクを軽減できます。