在Spring Cloud Gateway筛选器中引发自定义运行时异常

bvhaajcl  于 2022-12-17  发布在  Spring
关注(0)|答案(2)|浏览(147)

我们正在使用带有Sping Boot 2和React式WebFlux模块的Spring云网关。
有一个 authentication filter 是为其中一个路由添加的。现在如果我们抛出一个带有特定状态代码的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内部服务器 * 错误。这是从哪里来的?我们可以从这里的过滤器得到错误吗?

cwtwac6a

cwtwac6a1#

您可以实现一个自定义错误处理程序,下面是 Boot 文档。
或者你可以简单地抛出一个ResponseStatusException,默认的错误处理程序将呈现特定的状态。

jbose2ul

jbose2ul2#

请记住,在撰写本文时,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());
        };
    }

相关问题