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

如何将@PreAuthorize内的SecurityExpressionRoot传入自定义校验方法

实现方案

完全可以实现,不需要复杂扩展,Spring EL本身提供的内置变量就可以直接拿到你要的SecurityExpressionRoot实例。


方案一:直接传SpEL内置根对象(无额外配置,成本最低)

Spring在解析@PreAuthorize里的表达式时,会把MethodSecurityExpressionRoot(SecurityExpressionRoot的子类,针对方法级权限校验做了扩展)作为表达式的根对象,你可以直接通过SpEL内置的#root变量引用这个实例,直接作为参数传入你的自定义方法即可。

代码修改

  1. 调整Controller中@PreAuthorize注解的参数:
public class TestController {

    private final PreAuthorizeChecker preAuthorizeChecker;

    @Autowired
    public TestController(PreAuthorizeChecker preAuthorizeChecker) {
        this.preAuthorizeChecker = preAuthorizeChecker;
    }

    @GetMapping(path = "/test")
    // 直接传入#root即可获取当前请求对应的SecurityExpressionRoot实例
    @PreAuthorize("@preAuthorizeChecker.checkAccess(#root)")
    public ResponseEntity<Void> get() {
        return ResponseEntity.ok().build();
    }
}
  1. 调整校验类的方法参数(可选,建议用实际运行时类型避免类型转换问题):
    运行时实际传入的是MethodSecurityExpressionRoot实例,它继承自SecurityExpressionRoot,你既可以直接用父类声明参数,也可以用子类声明来访问方法级安全的扩展能力:
@Component
public class PreAuthorizeChecker {

    public boolean checkAccess(MethodSecurityExpressionRoot expressionRoot) {
        // 可以直接调用原生方法
        boolean hasBasePerm = expressionRoot.hasAuthority("test:access");
        // 可以获取当前认证信息做自定义校验
        Authentication currentUser = expressionRoot.getAuthentication();
        // 写你的自定义校验逻辑
        return hasBasePerm && /* 自定义判断条件 */ true;
    }
}

方案二:扩展原生Security表达式根(适合多规则场景)

如果你有大量自定义权限校验逻辑,不想每次在注解里写bean名称调用方法,可以直接扩展原生的MethodSecurityExpressionRoot,把你的校验方法注册为原生表达式方法,和hasAuthority()、hasRole()这类内置方法平级调用,不需要额外传根对象。
大致实现步骤:

  • 自定义表达式根类继承MethodSecurityExpressionRoot,在类中写你的checkAccess等自定义校验方法
  • 自定义MethodSecurityExpressionHandler,创建表达式实例时返回你自定义的根对象
  • 在Spring Security的方法级安全配置中,注册你自定义的ExpressionHandler

配置完成后你可以直接在注解里写@PreAuthorize("checkAccess()"),方法内部可以直接调用所有内置权限方法,写法更简洁。


注意:不要尝试手动new SecurityExpressionRoot实例传入,这类实例没有绑定当前请求的认证上下文、方法参数、请求对象等信息,完全无法完成正常的权限校验。

内容的提问来源于stack exchange,提问作者Mateusz Maciejko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 04:36:55