第一个GRPC拦截器中的访问消息请求在第二个GRPC拦截器中的标头之前
我的问题类似于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()
处理。如何让消息拦截器先运行,然后再运行头拦截器?这有可能吗?有没有更好的方法来解决我错过的这个问题?
解决方案
我想出来了。基本上,我遵循了帖子here
中描述的内容我的FirstInterceptorReadTokenFromMessageBody
类现在如下所示:
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);
}
}
相关文章