Method Security in GraalVM Native Image
虽然 GraalVM Native Image 中支持 Method Security,但有些用例需要应用程序提供的附加提示。
Although Method Security is supported in GraalVM Native Image, there are some use cases that need additional hints provided by the application.
Using @PreAuthorize
and @PostAuthorize
Annotations
如果您有 UserDetails
或 Authentication
类 自定义实现,则使用 @PreAuthorize
和 @PostAuthorize
注释需要附加提示信息。
Using @PreAuthorize
and @PostAuthorize
annotations require additional hints if you have a custom implementation of UserDetails
or Authentication
classes.
我们举一个示例,其中您使用自定义实现 UserDetails
类如下所示,并且此实现由您的 UserDetailsService
返回:
Let’s take an example where you have a custom implementation of UserDetails
class as follows and that implementation is returned by your 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()
方法,如下所示:
And you want to use the isAdmin()
method inside a @PreAuthorize
annotation as follows:
@PreAuthorize("principal?.isAdmin()")
public String hello() {
return "Hello!";
}
请记住,您需要将 add Remember that you need to add |
如果您使用以上配置 run the native image 应用程序,那么在尝试调用 hello()
方法时,您将收到类似以下内容的错误:
If you run the native image of your application with the above configuration, you will get an error similar to the following when trying to invoke the hello()
method:
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 本机图像在默认情况下不支持反射。
Which means that the isAdmin()
method cannot be found on the CustomUserDetails
class.
This is because Spring Security uses reflection to invoke the isAdmin()
method and GraalVM Native Image does not support reflection by default.
要解决这个问题,你需要给 GraalVM Native Image 提供提示以允许对 CustomUserDetails#isAdmin()
方法进行反射。我们可以通过提供一个 custom hint 来做到这一点。在此示例中,我们将使用 {spring-framework-reference-url}core.html#core.aot.hints.register-reflection-for-binding[@RegisterReflectionForBinding
注释]。
To fix this issue, you need to give hints to GraalVM Native Image to allow reflection on the CustomUserDetails#isAdmin()
method.
We can do that by providing a custom hint.
In this example we are going to use {spring-framework-reference-url}core.html#core.aot.hints.register-reflection-for-binding[the @RegisterReflectionForBinding
annotation].
您可能需要注册您想在 You might need to register all your classes that you want to use in your |
@Configuration
@RegisterReflectionForBinding(CustomUserDetails.class)
public class MyConfiguration {
//...
}
就是这样,现在您可以运行应用程序的本机映像了,并且它应该按预期工作。
And that’s it, now you can run the native image of your application and it should work as expected.