GraalVM 原生映象中的方法安全性
儘管 GraalVM 原生映象支援方法安全性,但某些用例需要應用程式提供額外的提示。
使用 @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!";
}
|
請記住,您需要在配置類中新增 |
如果您執行具有上述配置的應用程式的原生映象,當嘗試呼叫 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 原生映象預設不支援反射。
要解決此問題,您需要向 GraalVM 原生映象提供提示,以允許對 CustomUserDetails#isAdmin() 方法進行反射。我們可以透過提供自定義提示來做到這一點。在此示例中,我們將使用 @RegisterReflectionForBinding 註解。
|
您可能需要註冊所有您希望在 |
使用 @RegisterReflectionForBinding
@Configuration
@RegisterReflectionForBinding(CustomUserDetails.class)
public class MyConfiguration {
//...
}
就這樣,現在您可以執行應用程式的原生映象,它應該按預期工作。