Spring Cloud Gateway双安全过滤器链配置问题:/api异常403
问题分析与解决方案
你的配置核心问题在于未给每个SecurityFilterChain指定专属的请求匹配规则,导致优先级更高(@Order(1))的UI过滤器链会处理所有请求,包括/api路径的请求,进而让API过滤器链完全无法触发。
修正后的配置代码
UI路径过滤器链(仅处理/ui/**请求)
@Bean @Order(1) SecurityFilterChain securityFilterChain_UI(final HttpSecurity httpSecurity, final ClientRegistrationRepository clientRegistrationRepository) throws Exception { return httpSecurity // 明确仅匹配/ui/**开头的请求 .requestMatcher("/ui/**") .authorizeHttpRequests(exchanges -> exchanges .anyRequest().authenticated()) .oauth2Login(oAuth2LoginSpec -> oAuth2LoginSpec .failureHandler(authenticationFailureHandler())) .logout(logoutSpec -> logoutSpec .logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_URL, "GET")) .logoutSuccessHandler(logoutSuccessHandler(clientRegistrationRepository))) .cors(cors -> cors .configurationSource(corsConfigurationSource())) .csrf(AbstractHttpConfigurer::disable) .build(); }
API路径过滤器链(处理/api/**和/actuator/**请求)
@Bean @Order(2) SecurityFilterChain securityFilterChain_API(final HttpSecurity httpSecurity) throws Exception { return httpSecurity // 明确匹配/api/**和/actuator/**开头的请求 .requestMatcher("/api/**", "/actuator/**") .authorizeHttpRequests(exchanges -> exchanges .requestMatchers("/actuator/**").permitAll() .anyRequest().authenticated()) // 配置未授权时直接返回403,而非跳转登录 .exceptionHandling(exceptions -> exceptions .authenticationEntryPoint((request, response, authException) -> { response.setStatus(HttpStatus.FORBIDDEN.value()); response.getWriter().write("403 Forbidden"); })) // API无需OAuth2登录/登出流程,直接禁用 .oauth2Login(AbstractHttpConfigurer::disable) .logout(AbstractHttpConfigurer::disable) .cors(cors -> cors .configurationSource(corsConfigurationSource())) .csrf(AbstractHttpConfigurer::disable) .build(); }
关键调整说明
- 添加
requestMatcher规则:
每个过滤器链必须通过.requestMatcher()明确自己要处理的请求路径,这样Spring Security才会根据请求路径分发到对应的链中,避免高优先级链“包揽”所有请求。 - API链异常处理配置:
通过authenticationEntryPoint自定义未授权时的响应逻辑,直接返回403状态码,替代默认的跳转登录行为,符合API接口的需求。 - 移除API链不必要的配置:
API接口无需OAuth2登录、登出流程,直接禁用这些模块,减少冗余逻辑。
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

