SpringSecurityの@CurrentSecurityContextのガイド
1. 概要
Spring Securityは、認証クレデンシャルの受信と解析を処理します。
この短いチュートリアルでは、ハンドラーコード内で、リクエストからSecurityContext情報を取得する方法を見ていきます。
2. @CurrentSecurityContextアノテーション
ボイラープレートコードを使用して、セキュリティコンテキストを読み取ることができます。
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
ただし、現在、に役立つ@CurrentSecurityContextアノテーションがあります。
さらに、アノテーションを使用すると、コードがより宣言的になり、authenticationオブジェクトが注入可能になります。 @CurrentSecurityContext を使用すると、現在のユーザーのPrincipal実装にアクセスすることもできます。
以下の例では、認証やプリンシパルの名前など、セキュリティコンテキストデータを取得するいくつかの方法を見ていきます。 また、コードをテストする方法についても説明します。
3. Mavenの依存関係
Spring Bootの最新バージョンがある場合は、 spring-boot-starter-security:の依存関係を含めるだけで済みます。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
それ以外の場合は、spring-security-coreを最小バージョンの5.2.1.RELEASEにアップグレードできます。
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
4. @CurrentSecurityContextを使用した実装
SpEL(Spring Expression Language)と @CurrentSecurityContext を使用して、認証オブジェクトまたはプリンシパルを注入できます。 SpELはタイプルックアップと連携して機能します。 タイプチェックはデフォルトでは適用されませんが、@CurrentSecurityContextアノテーションのerrorOnInvalidTypeパラメーターを介して有効にできます。
4.1. 認証オブジェクトの取得
Authentication オブジェクトを読んで、その詳細を返すことができるようにしましょう。
@GetMapping("/authentication")
public Object getAuthentication(@CurrentSecurityContext(expression = "authentication")
Authentication authentication) {
return authentication.getDetails();
}
SpEL式は、認証オブジェクト自体を参照していることに注意してください。
それをテストしてみましょう:
@Test
public void givenOAuth2Context_whenAccessingAuthentication_ThenRespondTokenDetails() {
ClientCredentialsResourceDetails resourceDetails =
getClientCredentialsResourceDetails("baeldung", singletonList("read"));
OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails);
String authentication = executeGetRequest(restTemplate, "/authentication");
Pattern pattern = Pattern.compile("\\{\"remoteAddress\":\".*"
+ "\",\"sessionId\":null,\"tokenValue\":\".*"
+ "\",\"tokenType\":\"Bearer\",\"decodedDetails\":null}");
assertTrue("authentication", pattern.matcher(authentication).matches());
}
この例では、接続のすべての詳細を取得していることに注意してください。 テストコードではremoteAddressまたはtokenValueを予測できないため、正規表現を使用して結果のJSONを確認しています。
4.2. プリンシパルの取得
認証データからPrincipalのみが必要な場合は、SpEL式と挿入されたオブジェクトを変更できます。
@GetMapping("/principal")
public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal")
Principal principal) {
return principal.getName();
}
この場合、 getName メソッドを使用して、Principal名のみを返します。
それをテストしてみましょう:
@Test
public void givenOAuth2Context_whenAccessingPrincipal_ThenRespondBaeldung() {
ClientCredentialsResourceDetails resourceDetails =
getClientCredentialsResourceDetails("baeldung", singletonList("read"));
OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails);
String principal = executeGetRequest(restTemplate, "/principal");
assertEquals("baeldung", principal);
}
ここでは、クライアントの資格情報に追加された名前 baeldung が検出され、ハンドラーに挿入されたプリンシパルオブジェクト内から返されます。
5. 結論
この記事では、現在のセキュリティコンテキスト内のプロパティにアクセスし、ハンドラーメソッドのパラメーターにそれらを挿入する方法を見てきました。
これは、SpELと@CurrentSecurityContextアノテーションを利用して行いました。
いつものように、例の完全なソースコードは、GitHubでから入手できます。