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

Spring Security升级后自定义MethodSecurityExpressionRoot无法加载问题

解决Spring Security 5.8+中自定义MethodSecurityExpressionRoot不生效的问题

问题背景

将Spring Boot从2.3.0.RELEASE升级至2.7.8、Spring Security从5.7.6升级至5.8.1后,仅替换@EnableGlobalMethodSecurity(prePostEnabled = true)为@EnableMethodSecurity,运行Spock单元测试时抛出异常:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method internalUser(java.lang.String) cannot be found on type org.springframework.security.access.expression.method.MethodSecurityExpressionRoot

排查发现自定义的CustomMethodSecurityExpressionRoot未被使用,默认的MethodSecurityExpressionRoot被加载,且CustomMethodSecurityExpressionHandler中的createSecurityExpressionRoot方法未被调用。

问题原因

Spring Security 5.7+引入的@EnableMethodSecurity底层配置逻辑发生变化:它默认使用MethodSecurityConfiguration而非旧版的GlobalMethodSecurityConfiguration,原有的自定义MethodSecurityExpressionHandler注册方式不再被自动识别,导致自定义表达式根无法生效。

解决方案

修改MethodSecurityConfig,通过MethodSecurityCustomizer显式注册自定义表达式处理器,让Spring Security加载并使用你的CustomMethodSecurityExpressionRoot。

修改后的MethodSecurityConfig.java

@EnableMethodSecurity
public class MethodSecurityConfig {

    @Autowired
    private ApplicationContext context;

    @Bean
    public MethodSecurityCustomizer methodSecurityCustomizer() {
        // 为方法安全配置指定自定义表达式处理器
        return configurer -> configurer.expressionHandler(customExpressionHandler());
    }

    @Bean
    public CustomMethodSecurityExpressionHandler customExpressionHandler() {
        CustomMethodSecurityExpressionHandler handler = new CustomMethodSecurityExpressionHandler();
        handler.setApplicationContext(context);
        return handler;
    }
}

额外优化建议

  1. 移除CustomMethodSecurityExpressionHandler中无意义的构造代码:
// 删除这段无用代码
public CustomMethodSecurityExpressionHandler() {
    String stopHere = "stopHere";
}
  1. 修正CustomMethodSecurityExpressionRoot中setThis方法的访问权限(改为public,确保Spring Security能正常调用):
@Override
public void setThis(Object target) {
    this.target = target;
}

验证

重新运行Spock单元测试,此时Spring Security会触发CustomMethodSecurityExpressionHandler的createSecurityExpressionRoot方法,使用自定义的CustomMethodSecurityExpressionRoot,internalUser等自定义方法可被SpEL表达式正确识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:15:32