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

Spring Security 6.x基于表达式的访问控制失效问题求助

解决Spring Security中WebExpressionAuthorizationManager无法访问Bean的403问题

核心问题分析

错误栈中的关键提示 EL1057E: No bean resolver registered in the context to resolve access to bean 'webSecurity' 说明:WebExpressionAuthorizationManager 默认没有配置Spring容器的Bean解析器,导致SpEL表达式无法识别并调用容器中的webSecurity Bean,最终触发403授权失败。

解决方案

方案一:为WebExpressionAuthorizationManager配置Bean解析器

通过手动注入ApplicationContext,给WebExpressionAuthorizationManager设置带Bean解析能力的表达式处理器:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final ApplicationContext applicationContext;

    // 注入Spring上下文
    public SecurityConfig(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 创建带Bean解析能力的表达式处理器
        DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        
        // 初始化授权管理器并绑定处理器
        WebExpressionAuthorizationManager authorizationManager = 
            new WebExpressionAuthorizationManager("@webSecurity.check(authentication,request)");
        authorizationManager.setExpressionHandler(expressionHandler);

        return http
                .authorizeHttpRequests(authorize ->
                        authorize.requestMatchers("/test/**")
                                .access(authorizationManager)
                )
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().csrf().disable()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .build();
    }
}

方案二:改用类型安全的AuthorizationManager(推荐Spring Security 6+)

Spring Security 6+更推荐使用类型安全的AuthorizationManager替代SpEL表达式,避免Bean解析问题:

  1. 修改WebSecurity实现AuthorizationManager接口:
@Component
public class WebSecurityAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
        Authentication auth = authentication.get();
        HttpServletRequest request = context.getRequest();
        // 原check方法的授权逻辑
        return new AuthorizationDecision(true);
    }
}
  1. 在SecurityConfig中注入并使用该授权管理器:
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final WebSecurityAuthorizationManager webSecurityAuthorizationManager;

    public SecurityConfig(WebSecurityAuthorizationManager webSecurityAuthorizationManager) {
        this.webSecurityAuthorizationManager = webSecurityAuthorizationManager;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .authorizeHttpRequests(authorize ->
                        authorize.requestMatchers("/test/**")
                                .access(webSecurityAuthorizationManager)
                )
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().csrf().disable()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .build();
    }
}

方案对比

  • 方案一适合需要保留SpEL表达式写法的场景,通过补全Bean解析能力解决问题;
  • 方案二更符合Spring Security最新的设计理念,类型安全、易于调试维护,避免SpEL语法和Bean解析相关的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:47:20