Вы должны быть очень осторожны с ThreadLocals для этого типа контекстной информации, потому что вы не хотите случайно использовать неверную идентификационную информацию для клиента.
Каждый обратный вызов от gRPC может происходить в другом потоке, а обратные вызовы для нескольких RPC могут происходить в одном потоке.
Вам необходимо следовать шаблону, подобному Contexts.interceptCall () . Вы должны установить / сбросить после каждого звонка:
public class ImpersonationInterceptor {
public <ReqT, RespT> interceptCall(
ServerCall<ReqT, RespT> serverCall, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
Principal principal = ...;
AuthContext.setPrincipal(principal);
try {
return new WrappingListener<>(next.startCall(call, headers), principal);
} finally {
AuthContext.clearPrincipal();
}
}
private static class WrappingListener<ReqT> extends
ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT> {
private final Principal principal;
public WrappingListener(ServerCall.Listener<ReqT> delegate, Principal principal) {
super(delegate);
this.principal = principal;
}
@Override
public void onMessage(ReqT message) {
AuthContext.setPrincipal(principal);
try {
super.onMessage(message);
} finally {
AuthContext.clearPrincipal();
}
}
... repeat for each method
}
}