You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 6.3.3元注解使用报错,求问题排查

Spring Security元注解@PreAuthorize报错EL1008E的解决方法

你的问题出在两个核心点:

  1. 元注解中SpEL表达式无法直接访问注解属性
    在@PreAuthorize的表达式里,直接写hasAnyRole({roles})是错误的——SpEL默认不会将roles识别为自定义注解的属性,必须通过#this引用当前注解实例,才能正确访问它的roles属性。

  2. @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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 17:49:56