在第二个 gRPC 拦截器中 headers 之前在第一个 gRPC 拦截器中访问消息请求

Access message request in first gRPC interceptor before headers in second gRPC interceptor

我的问题类似于 post,但它似乎是旧的且不活跃的,所以我在这里重新post。

基本上,我有一个奇怪的用例,我需要在 gRPC 请求 body(而不是 header)中发送我的授权令牌。我的想法是使用一组拦截器,其中第一个将读取 gRPC 消息并根据消息中的令牌设置 Authorization header。第二个拦截器将是使用的正常授权拦截器,它将读取刚刚设置为 Authorization header 的令牌。我希望这样做,因为这样我就可以重用已经存在的授权拦截器代码。

我这样调用拦截器:

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() 处理,首先获得 header 授权,然后由 FirstInterceptorReadTokenFromMessageBody() 处理。我怎样才能先有消息拦截器 运行,然后有 header 拦截器?这可能吗?有没有更好的方法来解决我想念的这个问题?

我明白了。基本上,我遵循了线程 here

中描述的内容

我的 FirstInterceptorReadTokenFromMessageBody class 现在看起来像这样:

public class FirstInterceptorReadTokenFromMessageBody implements ServerInterceptor {
  @Override
  public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
      ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {

    final Listener<ReqT> authorizationLookUpCallListener =
        new ForwardingServerCallListener<ReqT>() {
          private final Listener<ReqT> NOOP = new Listener<ReqT>() {};
          private Listener<ReqT> delegate = NOOP;

          @Override
          protected Listener<ReqT> delegate() {
            return delegate;
          }

          @Override
          public void onMessage(ReqT message) {
            // ensures that this interceptor only run first
            if (delegate == NOOP) {
              if (message instanceof MyRequest) {
                String auth_token = ((MyRequest) message).getAuthToken();
                headers.put(
                    Metadata.Key.of("my-auth-token-header", Metadata.ASCII_STRING_MARSHALLER),
                    auth_token);
              }
              delegate = next.startCall(call, headers);
            }
            super.onMessage(message);
          }
        };

    ServerCallHandler<ReqT, RespT> handler =
        (call1, headers1) -> {
          call1.request(1);
          return authorizationLookUpCallListener;
        };

    return handler.startCall(call, headers);
  }
}