对于最新的稳定版本,请使用 Spring Security 7.0.4spring-doc.cadn.net.cn

Method Security in GraalVM Native Image

尽管在GraalVM Native Image中支持了方法安全,但仍有一些用例需要应用程序提供的额外提示。spring-doc.cadn.net.cn

使用@PreAuthorize@PostAuthorize注解

使用@PreAuthorize@PostAuthorize注解需要额外的提示,如果您自定义实现了UserDetailsAuthentication类。spring-doc.cadn.net.cn

让我们看一个例子,假设你有一个自定义的UserDetails类实现如下,并且该实现是由你的UserDetailsService返回的:spring-doc.cadn.net.cn

自定义实现 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注解:spring-doc.cadn.net.cn

使用isAdmin()来保护一个方法
@PreAuthorize("principal?.isAdmin()")
public String hello() {
    return "Hello!";
}

请记住,您需要向配置类 添加 @EnableMethodSecurity 注解 以启用方法安全注解。spring-doc.cadn.net.cn

如果使用上述配置运行你的应用程序的原生镜像,在尝试调用https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.developing-your-first-application方法时,你会遇到类似于以下错误:spring-doc.cadn.net.cn

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默认不支持反射。spring-doc.cadn.net.cn

要解决此问题,您需要向 GraalVM Native Image 提供提示,以允许对 CustomUserDetails#isAdmin() 方法进行反射。 我们可以通过提供 自定义提示 来实现这一点。 在本示例中,我们将使用 @RegisterReflectionForBinding 注解spring-doc.cadn.net.cn

您可能需要注册所有要在@PreAuthorize@PostAuthorize注解中使用的类。spring-doc.cadn.net.cn

使用 @RegisterReflectionForBinding
@Configuration
@RegisterReflectionForBinding(CustomUserDetails.class)
public class MyConfiguration {
    //...
}

现在已经完成了,现在你可以运行你的应用程序的原生镜像,并且它应该按预期工作。spring-doc.cadn.net.cn