Spring Security 6.3.3元注解使用报错,求问题排查
你的问题出在两个核心点:
元注解中SpEL表达式无法直接访问注解属性
在@PreAuthorize的表达式里,直接写hasAnyRole({roles})是错误的——SpEL默认不会将roles识别为自定义注解的属性,必须通过#this引用当前注解实例,才能正确访问它的roles属性。@HasAnyRole使用时参数格式错误
你传递的{"'USER'", "'ADMIN'"}带了额外单引号,这会导致Spring Security将角色识别为'USER'(包含单引号),而非预期的USER;同时hasAnyRole方法会自动为角色添加ROLE_前缀,不需要手动处理。
修正后的完整代码
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @SpringBootApplication @RestController @EnableMethodSecurity public class SpringProjectApplication { public static void main(String[] args) { SpringApplication.run(SpringProjectApplication.class, args); } @GetMapping(value = "/get") @HasAnyRole(roles = {"USER", "ADMIN"}) // 去掉多余单引号 public String get() { return "1"; } @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("hasAnyRole(#this.roles)") // 用#this引用当前注解的roles属性 public @interface HasAnyRole { String[] roles(); } }
关键说明
- #this的作用:在元注解的SpEL表达式中,
#this代表当前被标注的注解实例(即你的@HasAnyRole实例),通过#this.roles可以准确获取传入的角色数组。 - 角色参数规范:
hasAnyRole接收纯角色名称字符串,不需要添加单引号或ROLE_前缀,Spring Security会自动处理前缀逻辑(默认添加ROLE_,可通过配置自定义)。
内容的提问来源于stack exchange,提问作者yc ruan
相关产品推荐
相关产品推荐

