GraalVM ネイティブイメージのメソッドセキュリティ
メソッドのセキュリティは GraalVM ネイティブイメージでサポートされていますが、アプリケーションによって提供される追加のヒントが必要なユースケースがいくつかあります。
@PreAuthorize
および @PostAuthorize
アノテーションの使用
UserDetails
クラスまたは Authentication
クラスのカスタム実装がある場合、@PreAuthorize
および @PostAuthorize
アノテーションを使用するには追加のヒントが必要です。
次のような UserDetails
クラスのカスタム実装があり、その実装が UserDetailsService
によって返される例を考えてみましょう。
public class CustomUserDetails implements UserDetails {
private final String username;
private final String password;
private final Collection<? extends GrantedAuthority> authorities;
public boolean isAdmin() {
return this.authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
// constructors, getters and setters
}
そして、次のように @PreAuthorize
アノテーション内で isAdmin()
メソッドを使用したいとします。
@PreAuthorize("principal?.isAdmin()")
public String hello() {
return "Hello!";
}
メソッドのセキュリティアノテーションを有効にするには、構成クラスに |
上記の構成でアプリケーションのネイティブイメージを実行すると、hello()
メソッドを呼び出そうとしたときに次のようなエラーが発生します。
failed: java.lang.IllegalArgumentException: Failed to evaluate expression 'principal?.isAdmin()' with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method isAdmin() cannot be found on type com.mypackage.CustomUserDetails
これは、isAdmin()
メソッドが CustomUserDetails
クラスで見つからないことを意味します。これは、Spring Security がリフレクションを使用して isAdmin()
メソッドを呼び出し、GraalVM Native Image がデフォルトでリフレクションをサポートしていないためです。
この課題を解決するには、GraalVM Native Image にヒントを与えて、CustomUserDetails#isAdmin()
メソッドでの反映を可能にする必要があります。これは、カスタムヒントを提供することで実現できます。この例では、@RegisterReflectionForBinding
アノテーションを使用します。
|
@Configuration
@RegisterReflectionForBinding(CustomUserDetails.class)
public class MyConfiguration {
//...
}
これで、アプリケーションのネイティブイメージを実行できるようになり、期待どおりに動作するはずです。