1

我们已经实现StreamingHttpServiceFilter了对每个请求执行身份验证。

在身份验证不成功时,我们使用以下代码返回 401 Unauthorized 错误:

private StreamingHttpResponse createUnauthorizedResponse(final StreamingHttpResponseFactory responseFactory) {
        return responseFactory.unauthorized();
    }

当过滤器返回错误时,在客户端我们收到以下消息

GrpcStatus{code=INTERNAL, cause=null, description='HTTP status code: 401 Unauthorized invalid content-type: null headers: NettyH2HeadersToHttpHeaders[transfer-encoding: ]'}

如您所见, GrpcStatus 有code=INTERNAL,这意味着客户端需要解析description,并找出错误代码。

是否可以在准备来自过滤器的响应时添加任何其他元数据,以便代码可以UNAUTHENTICATED或者是否有任何客户端可用的工具可以读取描述并转换为 http 状态代码?

4

1 回答 1

2

gRPC 协议不太关注 HTTP 响应状态码,它总是期望200 OK. 其他状态代码将映射到INTERNALgRPC 代码。grpc-status相反,它依赖于grpc-messageHTTP/2 响应消息的预告片(或没有有效负载主体时的标头)。请参阅gRPC over HTTP2 文档中的响应部分。

当您处于 HTTP 级别并编写StreamingHttpServiceFilter. 时,您负责根据 gRPC 协议生成响应。最小响应是Trailers-Only并且包含HTTP-Status Content-Type Status [Status-Message] *Custom-Metadata

对于所描述的用例,手动生成适当的响应应该很容易。

另一种方法是GrpcStatusException从 gRPC 级别抛出一个:从服务端点或从 gRPC 过滤器。然后 ServiceTalk 会将该异常映射到具有所有必需标头字段的适当 HTTP/2 响应。

// Throws GrpcStatusException:
throw new GrpcStatus(GrpcStatusCode.UNAUTHENTICATED, null, "Your message for the client")
        .asException();

但是,在您的情况下,您可能需要StreamingHttpServiceFilter通过AsyncContext. 可能不值得。

于 2020-11-14T00:20:20.620 回答