• Java中使用GRPC(带TLS认证)


    0.编写.proto

    syntax = "proto3";
    
    option java_multiple_files = true;
    option java_package = "io.grpc.examples.helloworld";
    option java_outer_classname = "HelloWorldProto";
    option objc_class_prefix = "HLW";
    
    package helloworld;
    
    service Greeter {
        rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    
    message HelloRequest {
        string name = 1;
    }
    
    message HelloReply {
        string message = 1;
    }
    

      

    1.编译.proto生成Java源文件:

    protoc --grpc_out=..\java --plugin=protoc-gen-grpc=D:\Dev\protoc\protoc-gen-grpc-java-1.9.1-windows-x86_64.exe helloworld.proto
    protoc --java_out=..\java helloworld.proto
    

      

    2.生成CA根证书、服务器证书及客户端证书

    openssl genrsa -passout pass:111111 -des3 -out ca.key 4096
    openssl req -passin pass:111111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=localhost"
    openssl genrsa -passout pass:111111 -des3 -out server.key 4096
    openssl req -passin pass:111111 -new -key server.key -out server.csr -subj "/CN=localhost"
    openssl x509 -req -passin pass:111111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt 
    openssl rsa -passin pass:111111 -in server.key -out server.key
    openssl genrsa -passout pass:111111 -des3 -out client.key 4096
    openssl req -passin pass:111111 -new -key client.key -out client.csr -subj "/CN=localhost"
    openssl x509 -passin pass:111111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
    openssl rsa -passin pass:111111 -in client.key -out client.key
    openssl pkcs8 -topk8 -nocrypt -in client.key -out client.pem
    openssl pkcs8 -topk8 -nocrypt -in server.key -out server.pem
    

      

    3.编写Server端代码

    package io.grpc.examples.helloworldtls;
    
    import io.grpc.Server;
    import io.grpc.examples.helloworld.GreeterGrpc;
    import io.grpc.examples.helloworld.HelloReply;
    import io.grpc.examples.helloworld.HelloRequest;
    import io.grpc.netty.GrpcSslContexts;
    import io.grpc.netty.NettyServerBuilder;
    import io.grpc.stub.StreamObserver;
    import io.netty.handler.ssl.ClientAuth;
    import io.netty.handler.ssl.SslContextBuilder;
    import io.netty.handler.ssl.SslProvider;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.util.logging.Logger;
    
    public class HelloWorldServerTls {
        private static final Logger logger = Logger.getLogger(HelloWorldServerTls.class.getName());
    
        private Server server;
    
        private final String host;
        private final int port;
        private final String certChainFilePath;
        private final String privateKeyFilePath;
        private final String trustCertCollectionFilePath;
    
        public HelloWorldServerTls(String host,
                                   int port,
                                   String certChainFilePath,
                                   String privateKeyFilePath,
                                   String trustCertCollectionFilePath) {
            this.host = host;
            this.port = port;
            this.certChainFilePath = certChainFilePath;
            this.privateKeyFilePath = privateKeyFilePath;
            this.trustCertCollectionFilePath = trustCertCollectionFilePath;
        }
    
        private SslContextBuilder getSslContextBuilder() {
            SslContextBuilder sslClientContextBuilder = SslContextBuilder.forServer(new File(certChainFilePath),
                    new File(privateKeyFilePath));
            if (trustCertCollectionFilePath != null) {
                sslClientContextBuilder.trustManager(new File(trustCertCollectionFilePath));
                sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
            }
            return GrpcSslContexts.configure(sslClientContextBuilder,
                    SslProvider.OPENSSL);
        }
    
        private void start() throws IOException {
            server = NettyServerBuilder.forAddress(new InetSocketAddress(host, port))
                    .addService(new GreeterImpl())
                    .sslContext(getSslContextBuilder().build())
                    .build()
                    .start();
            logger.info("Server started, listening on " + port);
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    // Use stderr here since the logger may have been reset by its JVM shutdown hook.
                    System.err.println("*** shutting down gRPC server since JVM is shutting down");
                    HelloWorldServerTls.this.stop();
                    System.err.println("*** server shut down");
                }
            });
        }
    
        private void stop() {
            if (server != null) {
                server.shutdown();
            }
        }
    
        private void blockUntilShutdown() throws InterruptedException {
            if (server != null) {
                server.awaitTermination();
            }
        }
    
        public static void main(String[] args) throws IOException, InterruptedException {
    
            if (args.length < 4 || args.length > 5) {
                System.out.println(
                        "USAGE: HelloWorldServerTls host port certChainFilePath privateKeyFilePath " +
                        "[trustCertCollectionFilePath]
      Note: You only need to supply trustCertCollectionFilePath if you want " +
                        "to enable Mutual TLS.");
                System.exit(0);
            }
    
            final HelloWorldServerTls server = new HelloWorldServerTls(args[0],
                    Integer.parseInt(args[1]),
                    args[2],
                    args[3],
                    args.length == 5 ? args[4] : null);
            server.start();
            server.blockUntilShutdown();
        }
    
        static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    
            @Override
            public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
                HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
                responseObserver.onNext(reply);
                responseObserver.onCompleted();
            }
        }
    }
    

      

    4.编写Client端代码

    package io.grpc.examples.helloworldtls;
    
    import io.grpc.ManagedChannel;
    import io.grpc.StatusRuntimeException;
    import io.grpc.examples.helloworld.GreeterGrpc;
    import io.grpc.examples.helloworld.HelloReply;
    import io.grpc.examples.helloworld.HelloRequest;
    import io.grpc.examples.helloworld.HelloWorldServer;
    import io.grpc.netty.GrpcSslContexts;
    import io.grpc.netty.NegotiationType;
    import io.grpc.netty.NettyChannelBuilder;
    import io.netty.handler.ssl.SslContext;
    import io.netty.handler.ssl.SslContextBuilder;
    
    import javax.net.ssl.SSLException;
    import java.io.File;
    import java.util.concurrent.TimeUnit;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class HelloWorldClientTls {
        private static final Logger logger = Logger.getLogger(HelloWorldClientTls.class.getName());
    
        private final ManagedChannel channel;
        private final GreeterGrpc.GreeterBlockingStub blockingStub;
    
        private static SslContext buildSslContext(String trustCertCollectionFilePath,
                                                  String clientCertChainFilePath,
                                                  String clientPrivateKeyFilePath) throws SSLException {
            SslContextBuilder builder = GrpcSslContexts.forClient();
            if (trustCertCollectionFilePath != null) {
                builder.trustManager(new File(trustCertCollectionFilePath));
            }
            if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {
                builder.keyManager(new File(clientCertChainFilePath), new File(clientPrivateKeyFilePath));
            }
            return builder.build();
        }
    
        public HelloWorldClientTls(String host,
                                   int port,
                                   SslContext sslContext) throws SSLException {
    
            this(NettyChannelBuilder.forAddress(host, port)
                    .negotiationType(NegotiationType.TLS)
                    .sslContext(sslContext)
                    .build());
        }
    
        HelloWorldClientTls(ManagedChannel channel) {
            this.channel = channel;
            blockingStub = GreeterGrpc.newBlockingStub(channel);
        }
    
        public void shutdown() throws InterruptedException {
            channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
        }
    
        public void greet(String name) {
            logger.info("Will try to greet " + name + " ...");
            HelloRequest request = HelloRequest.newBuilder().setName(name).build();
            HelloReply response;
            try {
                response = blockingStub.sayHello(request);
            } catch (StatusRuntimeException e) {
                logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                return;
            }
            logger.info("Greeting: " + response.getMessage());
        }
    
        public static void main(String[] args) throws Exception {
            if (args.length < 2 || args.length == 4 || args.length > 5) {
                System.out.println("USAGE: HelloWorldClientTls host port [trustCertCollectionFilePath] " +
                        "[clientCertChainFilePath] [clientPrivateKeyFilePath]
      Note: clientCertChainFilePath and " +
                        "clientPrivateKeyFilePath are only needed if mutual auth is desired. And if you specify " +
                        "clientCertChainFilePath you must also specify clientPrivateKeyFilePath");
                System.exit(0);
            }
    
            {
                HelloWorldClientTls client;
                switch (args.length) {
                    case 2:
                        client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]),
                                buildSslContext(null, null, null));
                        break;
                    case 3:
                        client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]),
                                buildSslContext(args[2], null, null));
                        break;
                    default:
                        client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]),
                                buildSslContext(args[2], args[3], args[4]));
                }
    
                try {
                    String user = "world";
                    if (args.length > 0) {
                        user = args[0]; /* Use the arg as the name to greet if provided */
                    }
                    client.greet(user);
                } finally {
                    client.shutdown();
                }
            }
        }
    }
    

    5.分别运行Server、Client代码:

      (Server端加入运行参数:localhost 50051 D:openssl-keysserver.crt D:openssl-keysserver.pem)

      (Client端加入运行参数:localhost 50051 D:openssl-keysca.crt D:openssl-keysclient.crt D:openssl-keysclient.pem)

    运行如下:

  • 相关阅读:
    bzoj2819: Nim
    bzoj4864: [BeiJing 2017 Wc]神秘物质
    【转】 随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比
    【转】梯度下降算法原理
    梯度下降算法的一点认识(Ng第一课)
    快速理解webStroage
    Css选择器实例
    Canvas实例
    HTML5中的Canvas
    骰子效果实例
  • 原文地址:https://www.cnblogs.com/areful/p/10404982.html
Copyright © 2020-2023  润新知