在 Spring 云网关筛选器中抛出自定义运行时异常



我们正在将Spring Cloud Gateway与Spring Boot 2和反应式WebFlux模块一起使用。

为其中一个路由添加了身份验证过滤器。现在,如果我们抛出一个带有特定状态代码的 RuntimeException,它实际上不会拾取。

早些时候,此身份验证检查是 Spring 中 HandlerInterceptor 的一部分,但现在我们不能将 Web 模块与 WebFlux 一起使用(来自 Spring 云网关的冲突(。

例:

@Override
public GatewayFilter apply(Object config) {
ServerHttpRequest httpRequest = exchange.getRequest();
if(!someUtil.validRequest(httpRequest) {
throw new RuntimeException("Throw 401 Unauthorized with Custom error code and message");
}
}

目前,实际响应始终给出500 内部服务器错误。这是从哪里来的?我们可以在这里掌握过滤器的错误吗?

您可以实现自定义错误处理程序,这里是 Spring Boot 文档。

或者你可以简单地抛出一个 ResponseStatusException。默认错误处理程序将呈现特定状态。

请记住,在撰写本文时,spring-cloud-gateway使用Spring Framework WebFlux。这意味着方法会有所不同。您可以在筛选器中获取异常,如下所示。

声明如下异常:

public class UnauthorisedException extends ResponseStatusException {
public UnauthorisedException(HttpStatusCode status) {
super(status);
}
public UnauthorisedException(HttpStatusCode status, String reason) {
super(status, reason);
}
}

注意:异常扩展了 ResponseStatusException。

ControllerAdvice 类可以按如下方式实现:

@ControllerAdvice
public class MyErrorWebExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(UnauthorisedException.class)
public Mono<ServerResponse> handleIllegalState(ServerWebExchange exchange, UnauthorisedException exc) {
exchange.getAttributes().putIfAbsent(ErrorAttributes.ERROR_ATTRIBUTE, exc);
return ServerResponse.from(ErrorResponse.builder(exc,HttpStatus.FORBIDDEN,exc.getMessage()).build());
}
}

在筛选器中,现在可以实现apply方法,如下所示:

public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
if (request.getHeaders().get("token") == null){ //test is an example
throw new UnauthorisedException(HttpStatus.FORBIDDEN, "Not Authorised from Gateway");
}
ServerHttpRequest.Builder builder = request.mutate();
return chain.filter(exchange.mutate().request(builder.build()).build());
};
}

最新更新