1. 序章

Spring Securityでは、認証されたユーザーが特定の役割を持っているかどうかを確認する必要がある場合があります。 これは、アプリケーションの特定の機能を有効または無効にするのに役立ちます

このチュートリアルでは、JavaでSpringセキュリティのユーザーロールを確認するさまざまな方法を紹介します。

2. Javaでのユーザーロールの確認

Spring Securityは、Javaコードでユーザーロールをチェックするいくつかの方法を提供します。 以下でそれぞれを見ていきます。

2.1. @PreAuthorize

Javaでユーザーの役割を確認する最初の方法は、SpringSecurityが提供する@PreAuthorizeアノテーションを使用することです。 このアノテーションはクラスまたはメソッドに適用でき、SpEL式を表す単一の文字列値を受け入れます。

このアノテーションを使用する前に、まずグローバルメソッドセキュリティを有効にする必要があります。 これは、Javaコードで、@EnableGlobalMethodSecurityアノテーションを任意の構成クラスに追加することで実行できます。

次に、 Spring Securityは、@PreAuthorizeアノテーションで使用できる2つの式を提供してユーザーロールをチェックします。

@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") String id) {
    ...
}

1つの式で複数の役割を確認することもできます。

@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MANAGER')")
@GetMapping("/users")
public String getUsers() {
    ...
}

この場合、ユーザーが指定されたロールの any を持っている場合、リクエストは許可されます。

適切な役割を持たずにメソッドが呼び出されると、Spring Securityは例外をスローし、エラーページにリダイレクトします。

2.2. SecurityContext

Javaコードでユーザーロールを確認する次の方法は、SecurityContextクラスを使用することです。

デフォルトでは、SpringSecurityはこのクラスのスレッドローカルコピーを使用します。 つまり、アプリケーションの各リクエストには、リクエストを行ったユーザーの詳細を含むセキュリティコンテキストがあります

これを使用するには、SecurityContextHolderの静的メソッドを呼び出すだけです。

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ADMIN"))) {
    ...
}

ここでは、完全な役割名ではなく、プレーンな権限名を使用していることに注意してください。

これは、たとえば、単一のメソッドの特定の部分など、よりきめ細かいチェックが必要な場合にうまく機能します。 ただし、Spring Security でグローバルコンテキストホルダーモードを使用する場合、このアプローチは機能しません。

2.3. UserDetailsService

Javaコードでユーザーロールを検索する3番目の方法は、UserDetailsServiceを使用することです。 これは、アプリケーションのどこにでも挿入して、必要に応じて呼び出すことができるBeanです。

@GetMapping("/users")
public String getUsers() {
    UserDetails details = userDetailsService.loadUserByUsername("mike");
    if (details != null && details.getAuthorities().stream()
      .anyMatch(a -> a.getAuthority().equals("ADMIN"))) {
        // ...
    }
}

ここでも、プレフィックス付きの完全なロール名ではなく、権限名を使用する必要があります。

このアプローチの利点は、リクエストを行ったユーザーだけでなく、すべてのユーザーの役割を確認できることです。

2.4. サーブレットリクエスト

Spring MVC を使用している場合は、HttpServletRequestクラスを使用してJavaのユーザーロールを確認することもできます。

@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
    if (request.isUserInRole("ROLE_ADMIN")) {
        ...
    }
}

3. 結論

この記事では、SpringSecurityでJavaコードを使用してロールをチェックするいくつかの異なる方法を見てきました。

いつものように、この記事のコード例はGitHubにあります。