【发布时间】:2021-09-10 19:33:34
【问题描述】:
我的问题类似于this 的帖子,但它似乎很旧且不活跃,所以我在这里重新发布。
基本上,我有一个奇怪的用例,我需要在 gRPC 请求正文(而不是标头)中发送我的授权令牌。我的想法是使用一组拦截器,其中第一个将读取 gRPC 消息并根据消息中的令牌设置 Authorization 标头。第二个拦截器将是使用的普通授权拦截器,它将读取刚刚设置为 Authorization 标头的令牌。我希望这样做,因为这样可以让我重用已经存在的授权拦截器代码。
我这样称呼拦截器:
ServerInterceptors.intercept(
new MyResource(resource),
new SecondInterceptorHeaderAuthorization(),
new FirstInterceptorReadTokenFromMessageBody()
)
FirstInterceptorReadTokenFromMessageBody() 看起来像这样:
public class FirstInterceptorReadTokenFromMessageBody implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(
next.startCall(call, headers)) {
@Override
public void onMessage(ReqT request) {
var value = ((MyRequest) request).getAuthorization();
Metadata.Key<String> key =
Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER);
headers.put(key, value);
super.onMessage(request);
}
};
}
}
还有SecondInterceptorHeaderAuthorization()拦截器:
public class SecondInterceptorHeaderAuthorization implements ServerInterceptor {
public <ReqT, RespT> Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
.... handle authorization here
}
拦截器以相反的顺序正确触发;请求最终由SecondInterceptorHeaderAuthorization() 处理,首先是标题授权,然后是FirstInterceptorReadTokenFromMessageBody()。我怎样才能让消息拦截器先运行,然后是标头拦截器?这甚至可能吗?有没有更好的方法来解决我错过的这个问题?
【问题讨论】:
-
我认为你应该把 header 放在客户端的 Metadata 中,就像 traceId rathar 一样,而不是放在 message 中,所以你只需要一个拦截器来处理授权,并且可以直接从 header 中读取。
-
很乐意这样做,除了请求通过的代理正在剥离所有标头。我想我已经找到了解决方案。等我有几分钟的时间再写。