GraalVM Native Image 中的方法安全
儘管 方法安全 在 GraalVM Native Image 中受支援,但某些用例需要應用程式提供額外的提示。
使用 @PreAuthorize
和 @PostAuthorize
註解
如果你有 UserDetails
或 Authentication
類的自定義實現,使用 @PreAuthorize
和 @PostAuthorize
註解需要額外的提示。
假設你有一個如下所示的 UserDetails
類的自定義實現,並且該實現由你的 UserDetailsService
返回
UserDetails 的自定義實現
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()
方法,如下所示
使用 isAdmin() 來保護方法
@PreAuthorize("principal?.isAdmin()")
public String hello() {
return "Hello!";
}
請記住,你需要在你的配置類上新增 |
如果你使用上述配置執行你的應用程式的 Native Image,當嘗試呼叫 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
這意味著在 CustomUserDetails
類上找不到 isAdmin()
方法。這是因為 Spring Security 使用反射來呼叫 isAdmin()
方法,而 GraalVM Native Image 預設不支援反射。
為了解決這個問題,你需要給 GraalVM Native Image 提供提示,以允許對 CustomUserDetails#isAdmin()
方法進行反射。我們可以透過提供自定義提示來實現這一點。在本例中,我們將使用@RegisterReflectionForBinding
註解。
你可能需要註冊所有你想在 |
使用 @RegisterReflectionForBinding
@Configuration
@RegisterReflectionForBinding(CustomUserDetails.class)
public class MyConfiguration {
//...
}
就是這樣,現在你可以執行你的應用程式的 Native Image,它應該按預期工作。