Spring Securityを使用したユニットテスト 質問する

Spring Securityを使用したユニットテスト 質問する

私の会社では、次のプロジェクトの 1 つで Spring MVC を使用するかどうかを判断するために、Spring MVC を評価してきました。これまでのところ、私は Spring MVC に満足しており、現在は Spring Security モジュールを調べて、それが使用できるか、または使用すべきかどうかを判断しています。

当社のセキュリティ要件は非常に基本的なものです。ユーザーは、サイトの特定の部分 (アカウントに関する情報の取得など) にアクセスするために、ユーザー名とパスワードを入力するだけで済みます。また、匿名ユーザーにアクセスを許可するページ (FAQ、サポートなど) もいくつかあります。

私が作成しているプロトタイプでは、認証されたユーザーのセッションに「LoginCredentials」オブジェクト (ユーザー名とパスワードのみを含む) を保存しています。一部のコントローラーは、たとえばログインしたユーザー名への参照を取得するために、このオブジェクトがセッション内にあるかどうかを確認します。この自家製ロジックを Spring Security に置き換えようと考えています。これにより、コントローラー/ビジネス コードから「ログインしたユーザーをどのように追跡するか?」や「ユーザーをどのように認証するか?」といった問題をすべて取り除くことができるという利点があります。

Spring Security は、アプリ内のどこからでもユーザー名/プリンシパル情報にアクセスできるように、(スレッドごとに)「コンテキスト」オブジェクトを提供しているようです...

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

...このオブジェクトはある意味では (グローバル) シングルトンなので、Spring らしくないように思えます。

私の質問は次のとおりです。これが Spring Security で認証されたユーザーに関する情報にアクセスするための標準的な方法である場合、ユニット テストで認証されたユーザーが必要なときに、ユニット テストで使用できるように、Authentication オブジェクトを SecurityContext に挿入するための受け入れられる方法は何ですか。

各テストケースの初期化メソッドでこれを接続する必要がありますか?

protected void setUp() throws Exception {
    ...
    SecurityContextHolder.getContext().setAuthentication(
        new UsernamePasswordAuthenticationToken(testUser.getLogin(), testUser.getPassword()));
    ...
}

これは冗長すぎるようです。もっと簡単な方法はありますか?

オブジェクトSecurityContextHolder自体はとても春らしくないようです...

ベストアンサー1

通常の方法で実行し、SecurityContextHolder.setContext()テスト クラスに挿入します。例:

コントローラ:

Authentication a = SecurityContextHolder.getContext().getAuthentication();

テスト:

Authentication authentication = Mockito.mock(Authentication.class);
// Mockito.whens() for your authorization object
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);

おすすめ記事