对于最新的稳定版本,请使用 Spring Security 6.5.3! |
GraalVM 原生映像中的方法安全性
尽管 GraalVM 本机映像支持方法安全性,但某些用例需要应用程序提供的其他提示。
用@PreAuthorize
和@PostAuthorize
附注
用@PreAuthorize
和@PostAuthorize
如果你有自定义实现UserDetails
或Authentication
类。
让我们举一个例子,其中您有一个自定义实现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
}
并且您想使用isAdmin()
方法@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 本机映像提供提示,以允许对CustomUserDetails#isAdmin()
方法。
我们可以通过提供自定义提示来做到这一点。
在这个例子中,我们将使用这@RegisterReflectionForBinding
注解.
您可能需要注册要在 |
使用 @RegisterReflectionForBinding
@Configuration
@RegisterReflectionForBinding(CustomUserDetails.class)
public class MyConfiguration {
//...
}
就是这样,现在您可以运行应用程序的本机映像,它应该按预期工作。