【问题标题】:How to create Insecure Java grpc cilent for secure go grpc service如何为安全的 go grpc 服务创建不安全的 Java grpc 客户端
【发布时间】:2019-04-29 12:11:23
【问题描述】:

我正在尝试在 Java 中创建 grpc 服务客户端,其中服务器位于 goLang 中并使用 https 进行部署。我正在尝试实现非安全连接[我不想通过证书]

public class testgrpc {
    ManagedChannel channel ;
    ServiceGrpc.ServiceBlockingStub  blockingStub;
    String host = "remotesecuredhost";
    int port ="XXX";

    @Test
    public void testgrpc()
    {
    channel = ManagedChannelBuilder.forAddress(host,port).build();

     blockingStub = ServiceGrpc.newBlockingStub(channel);

    response =  blockingStub.health(Empty.newBuilder().build());

    }

}

上面的代码给出了以下异常

io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
    at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:221)
    at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:202)
    at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:131)

有人可以帮忙处理客户端代码

【问题讨论】:

  • 不想通过证书是什么意思? Go 服务器是否使用自定义 CA 作为其证书?
  • 不是自定义的,而是特定于环境的自签名证书
  • 或者换句话说我想绕过安全证书步骤,这可能吗?
  • gRPC 强烈反对忽略证书,并且不“支持”忽略证书,因为这使得它实际上不安全;明文更容易使用。我们发现没有必要的用例,即使是使用 TLS 进行测试也是如此。在 Java 中可以通过提供您自己的 TrustManager 来实现,例如 Netty 的 InsecureTrustManagerFactory,但是在使用它时“您只能靠自己”。在您的情况下,您可以在服务器上使用硬编码的证书,仍然可以获得相同的效果,这将保持启用证书验证。
  • 我在 go lib --- conn, err := grpc.Dial(serverAddress, grpc.WithInsecure()) 中看到了这段代码,它还需要验证证书吗?您能帮忙处理一下 trustmanager 代码示例吗?

标签: java ssl go grpc grpc-java


【解决方案1】:

在我的情况下,我终于找到了解决方案

  1. Netty 版本在我的 build.gradle 中不同步,因为我收到了如下异常
Could not find TLS ALPN provider; no working netty-tcnative,
Conscrypt, or Jetty NPN/ALPN available

为了解决这个问题,我设置了以下版本

grpc-netty - 1.20.x- ||| netty-handler-4.1.34.Final ||| netty-tcnative-boringssl-静态版本 2.0.22.Final got idea from here

  1. tls 连接有效
channel  = NettyChannelBuilder
                .forAddress("host",port)
               .sslContext(GrpcSslContexts.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build())
                .build();

  1. 对于非 tls

              channel  = NettyChannelBuilder
            .forAddress("host",port).usePlaintext()
       .build();

【讨论】:

    【解决方案2】:
    
    import java.util.concurrent.TimeUnit;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import io.grpc.ManagedChannel;
    import io.grpc.ManagedChannelBuilder;
    import io.grpc.StatusRuntimeException;
    import io.kubesure.publish.PublisherGrpc;
    import io.kubesure.publish.PublisherProtos.Ack;
    import io.kubesure.publish.PublisherProtos.Message;
    import io.kubesure.publish.PublisherProtos.Message.Builder;
    
    public class AppClient {
    
        private static final Logger logger = Logger.getLogger(AppClient.class.getName());
        private final ManagedChannel channel;
        private final PublisherGrpc.PublisherBlockingStub blockingStub;
    
        public AppClient(String host, int port) {
            this(ManagedChannelBuilder.forAddress(host, port)
                    // Channels are secure by default (via SSL/TLS). For the example we disable TLS
                    // to avoid
                    // needing certificates.
                    .usePlaintext().build());
        }
    
        AppClient(ManagedChannel channel) {
            this.channel = channel;
            blockingStub = PublisherGrpc.newBlockingStub(channel);
        }
    
        public Ack publish(String payload) {
            logger.info("Payload sent to publisher ");
            Builder builder = Message.newBuilder();
            builder.setPayload(payload);
            builder.setVersion("v1");
            builder.setType("Policy");
            builder.setDestination("policyissued");
            Message message = builder.build();
            try {
                Ack ack = blockingStub.publish(message);
                logger.info("is published: " + ack.getOk());
                return ack;
            } catch (StatusRuntimeException e) {
                logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                return Ack.newBuilder().setOk(false).build(); 
            }
        }
    
        public void shutdown() throws InterruptedException {
            channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
        }
    
        public static void main(String[] args) throws Exception {
            AppClient client = new AppClient("localhost", 50051);
            try {
                /* Access a service running on the local machine on port 50051 */
                String payload = "supplies to mars";
                if (args.length > 0) {
                    payload = args[0]; /* Use the arg as the name to greet if provided */
                }
                client.publish(payload);
            } finally {
                client.shutdown();
            }
        }
    }
    

    【讨论】:

    • 在我的情况下,如果我用我的服务运行类似的代码,它会抛出 INTERNAL: http2 exception io.grpc.StatusRuntimeException: INTERNAL: http2 exception at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls. java:221) 在 io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:202) 在 io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:131)
    猜你喜欢
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    相关资源
    最近更新 更多