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
相关产品推荐
相关产品推荐

