如何访问我定义的 java grpc 服务的请求元数据? [英] How do I access request metadata for a java grpc service I am defining?

查看:34
本文介绍了如何访问我定义的 java grpc 服务的请求元数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于某些背景,我尝试使用 grpcauth 以便为我定义的某些服务提供安全性.

For some background, I am attempting to use grpc auth in order to provide security for some services I am defining.

让我们看看我是否可以问这是一种有意义的方式.对于我的 python 代码,实现服务器端代码非常容易.

Let's see if I can ask this is a way that makes sense. For my python code, it was pretty easy to implement the server side code.

class TestServiceServer(service_pb2.TestServiceServer):

    def TestHello(self, request, context):

        ## credential metadata for the incoming request
        metadata = context.invocation_metadata()

        ## authenticate the user using the metadata

因此,如您所知,我可以很容易地从上下文"中获取元数据.对我来说更难的是在java中做同样的事情.

So, as you can tell, I am able to get the metadata from "context" quite easily. What is harder for me is to do the same thing in java.

public class TestImpl extends TestServiceGrpc.TestServiceImplBase {

    @Override
    public void testHello(TestRequest req, StreamObserver<TestResponse> responseObserver) {

        // How do I get access to similar request metadata here?

        // from the parameter positions, it looks like it should be
        // "responseObserver" but that doesn't seem similar to "context"

    }

}

我承认我的问题来自几个方面.

I'll admit my problem comes from a few directions.

1) 我不精通 Java

1) I am not well versed in Java

2) 我大量使用 python 的pdb"来调试类并查看我可以使用哪些方法.我不知道/不精通 java 的类似工具.

2) I heavily used python's "pdb" in order to debug the classes and see what methods are available to me. I don't know of/am not proficient at a similar tool for java.

3) 在这一点上,文档似乎相当稀少.它向您展示了如何在服务器端设置 ssl 连接,但我找不到服务器查看请求元数据的示例,如我在 python 中所示.

3) The documentation seems rather sparse at this point. It shows you how to set up an ssl connection on the server side, but I can't find an example of the server taking a look at request metadata, as I have shown in python.

有人可以告诉我如何做到这一点,或者像python的pdb一样向我展示一个有用的java调试工具吗?

Could someone please give me an idea of how to do this, or perhaps show me a useful debugging tool for java in the same vein of python's pdb?

编辑/回答:

我需要首先编写一个实现接口 ServerInterceptor 的定义.

I needed to first write a definition implementing the interface ServerInterceptor.

private class TestInterceptor implements ServerInterceptor {
    ....

然后,在实际绑定我的服务和构建我的服务器之前,我需要这样做.

Then, before actually binding my service and building my server, I needed to do this.

TestImpl service = new TestImpl();
ServerServiceDefinition intercepted = ServerInterceptors.intercept(service, new TestInterceptor());

现在我可以创建服务器了.

Now I was able to create the server.

server = NettyServerBuilder.forPort(port)

    // enable tls
    .useTransportSecurity(
        new File(serverCert),
        new File(serverKey)
    )
    .addService(
        intercepted  // had been "new TestImpl()"
    )
    .build();

server.start();

这允许在我触发客户端请求时实际调用我的 ServerInterceptor.

This allowed my ServerInterceptor to actually be called when I fired off a client side request.

此链接 对解决这个问题很有帮助.

This link was quite helpful in figuring this out.

推荐答案

使用 ServerInterceptor 然后通过 Context 传播身份.这使您可以拥有用于身份验证的中央策略.

Use a ServerInterceptor and then propagate the identity via Context. This allows you to have a central policy for authentication.

拦截器可以从 Metadata headers 中检索身份.然后它应该验证身份.然后可以通过 io.grpc.Context 将经过验证的身份传送给应用程序(即 testHello):

The interceptor can retrieve the identity from Metadata headers. It should then validate the identity. The validated identity can then be communicated to the application (i.e., testHello) via io.grpc.Context:

/** Interceptor that validates user's identity. */
class MyAuthInterceptor implements ServerInterceptor {
  public static final Context.Key<Object> USER_IDENTITY
      = Context.key("identity"); // "identity" is just for debugging

  @Override
  public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
      ServerCall<ReqT, RespT> call,
      Metadata headers,
      ServerCallHandler<ReqT, RespT> next) {
    // You need to implement validateIdentity
    Object identity = validateIdentity(headers);
    if (identity == null) { // this is optional, depending on your needs
      // Assume user not authenticated
      call.close(Status.UNAUTENTICATED.withDescription("some more info"),
                 new Metadata());
      return new ServerCall.Listener() {};
    }
    Context context = Context.current().withValue(USER_IDENTITY, identity);
    return Contexts.interceptCall(context, call, headers, next);
  }
}

public class TestImpl extends TestServiceGrpc.TestServiceImplBase {
  @Override
  public void testHello(TestRequest req, StreamObserver<TestResponse> responseObserver) {
    // Access to identity.
    Object identity = MyAuthInterceptor.USER_IDENTITY.get();
    ...
  }
}

// Need to use ServerInterceptors to enable the interceptor
Server server = ServerBuilder.forPort(PORT)
    .addService(ServerInterceptors.intercept(new TestImpl(),
        new MyAuthInterceptor()))
    .build()
    .start();

这篇关于如何访问我定义的 java grpc 服务的请求元数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆