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

WebFluxSecurity中OAuth Issuer不可用时自定义500错误响应方案

响应式Spring资源服务器自定义Keycloak不可用场景的500响应体方案

在Spring Security 6.2.0 + Spring Boot 3.2.0的响应式资源服务器中,认证环节的异常(如Keycloak发行方不可达)发生在Spring Security过滤器链阶段,早于Spring MVC的@ExceptionHandler生效时机,因此常规异常处理器无法捕获这类500错误。以下是两种可行的解决方案:


方案1:自定义认证入口点处理认证相关5xx异常

扩展ServerAuthenticationEntryPoint,针对认证过程中出现的发行方不可用异常,返回自定义响应。

1. 实现自定义认证入口点

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

public class CustomAuthEntryPoint implements ServerAuthenticationEntryPoint {
    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException ex) {
        // 匹配发行方不可达的异常特征(比如JWK集获取失败)
        if (ex.getMessage() != null && ex.getMessage().contains("Failed to retrieve JWK set")) {
            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
            String customResp = "{\"foo\": \"bar\"}";
            return exchange.getResponse().writeWith(
                Mono.just(exchange.getResponse().bufferFactory().wrap(customResp.getBytes()))
            );
        }
        // 其他认证异常(如401/403)保持原有逻辑
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }
}

2. 在Security配置中替换默认入口点

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange(exchanges -> exchanges.anyExchange().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.jwkSetUri("https://invalid-issuer.example.com/.well-known/jwks.json"))
                .authenticationEntryPoint(new CustomAuthEntryPoint())
            );
        return http.build();
    }
}

方案2:全局WebFlux异常处理器覆盖所有5xx错误

如果需要统一处理所有5xx服务器错误,可自定义ErrorWebExceptionHandler替换默认逻辑。

1. 实现全局异常处理器

import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

public class CustomErrorHandler implements ErrorWebExceptionHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        HttpStatus status = exchange.getResponse().getStatusCode();
        if (status != null && status.is5xxServerError()) {
            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
            String customResp = "{\"foo\": \"bar\"}";
            return exchange.getResponse().writeWith(
                Mono.just(exchange.getResponse().bufferFactory().wrap(customResp.getBytes()))
            );
        }
        // 非5xx异常按默认逻辑处理
        return Mono.error(ex);
    }
}

2. 注册全局异常处理器Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ErrorConfig {
    @Bean
    public CustomErrorHandler customErrorHandler() {
        return new CustomErrorHandler();
    }
}

关键提示

  • 认证环节的异常发生在Spring Security过滤器链中,未进入Spring MVC处理流程,因此@ExceptionHandler无法捕获。
  • 方案1更精准,仅处理认证相关的5xx异常;方案2覆盖所有5xx错误,可根据业务需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:53:13