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

Spring Boot 3中GlobalMethodSecurityConfiguration已弃用,如何创建自定义表达式处理器?

在Spring Boot 3中实现自定义方法安全表达式处理器

Spring Boot 3基于Spring Security 6,原有的GlobalMethodSecurityConfiguration和@EnableGlobalMethodSecurity已被废弃,需改用@EnableMethodSecurity注解结合Bean注册的方式来实现自定义表达式处理器,具体改造步骤如下:

1. 替换启用注解并重构配置类

不再继承GlobalMethodSecurityConfiguration,而是使用@EnableMethodSecurity开启方法安全,并通过@Bean注册自定义的MethodSecurityExpressionHandler:

@Configuration
@EnableMethodSecurity(prePostEnabled = true) // 替代原@EnableGlobalMethodSecurity
public class MethodSecurityConfig {

    private final ApplicationContext applicationContext;
    private final CustomPermissionEvaluator customPermissionEvaluator;

    // 构造注入,替代字段@Autowired
    public MethodSecurityConfig(ApplicationContext applicationContext,
                                CustomPermissionEvaluator customPermissionEvaluator) {
        this.applicationContext = applicationContext;
        this.customPermissionEvaluator = customPermissionEvaluator;
    }

    @Bean
    public MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
        CustomMethodSecurityExpressionHandler expressionHandler = new CustomMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(customPermissionEvaluator);
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }
}

2. 调整自定义表达式处理器(可选优化)

原CustomMethodSecurityExpressionHandler可保留核心逻辑,也可利用Spring依赖注入简化代码,直接注入所需Bean替代手动从ApplicationContext获取:

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {

    private final CustomTraversalSource customTraversalSource;
    private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();

    // 构造注入替代手动获取Bean
    public CustomMethodSecurityExpressionHandler(CustomTraversalSource customTraversalSource) {
        this.customTraversalSource = customTraversalSource;
    }

    @Override
    protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
                                                                             MethodInvocation invocation) {
        CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
        root.setPermissionEvaluator(getPermissionEvaluator());
        root.setTrustResolver(this.trustResolver);
        root.setRoleHierarchy(getRoleHierarchy());
        root.setG(customTraversalSource);
        return root;
    }
}

如果希望保留原有的setApplicationContext逻辑,也可以不修改该类,上述优化仅为贴合Spring依赖注入最佳实践。

3. 保留自定义权限评估器

原CustomPermissionEvaluator的逻辑无需修改,它本身是@Component会被Spring容器管理,可直接注入到配置类中:

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        if ((authentication == null) || (targetDomainObject == null) || !(permission instanceof String)){
            return false;
        }
        String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase();
        
        return hasPrivilege(authentication, targetType, permission.toString().toUpperCase());
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
                                 Object permission) {
        if ((authentication == null) || (targetType == null) || !(permission instanceof String)) {
            return false;
        }
        return hasPrivilege(authentication, targetType.toUpperCase(), 
          permission.toString().toUpperCase());
    }

    private boolean hasPrivilege(Authentication authentication, String targetType, String permission) {
        for (GrantedAuthority grantedAuth : authentication.getAuthorities()) {
            if (grantedAuth.getAuthority().startsWith(targetType) && 
              grantedAuth.getAuthority().contains(permission)) {
                return true;
            }
        }
        return false;
    }
}

关键变化说明

  • @EnableMethodSecurity是@EnableGlobalMethodSecurity的替代注解,支持prePostEnabled、securedEnabled等相同配置属性。
  • 无需再继承GlobalMethodSecurityConfiguration,通过注册MethodSecurityExpressionHandler类型的Bean即可覆盖默认实现。
  • 优先使用构造注入替代字段注入,更符合Spring的依赖注入规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:05:22