使用root.pem文件以及客户端的用户名和密码对gRPC进行SSL / TLS身份验证。
要在C ++中使用根pem证书文件和凭据对gRPC服务器进行身份验证,我们提供了一种功能,可以从客户端提供两个选项,如下所示。
使用环境变量选项(C ++)设置PEM文件:
setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", fileBuff1, true);
sprintf(setSecBuff, "chmod 777 %s", fileBuff1);
system(setSecBuff);
使用ssl选项创建频道(如果有,则使用keyPassword):
SslCredentialsOptions ssl_opts;
TelemAsyncClient telemAsyncClient(grpc::CreateChannel(std::string(hostIpStr), grpc::SslCredentials(ssl_opts), ChannelArguments()));
使用ClientContext(C ++)传递凭据:
ClientContext context;
CompletionQueue cq;
Status status;
context.AddMetadata("username", userid);
context.AddMetadata("password", password);
// Print Populated GetRequest
printGetRequest(&getReq);
std::unique_ptr<ClientAsyncResponseReader<GetResponse> > rpc(stub_->AsyncGet(&context, getReq, &cq));
在Java中,我们可以传递pem文件,但是如何传递凭据? 传递pem文件的Java代码: ==========================
ManagedChannel channel = NettyChannelBuilder.forAddress(ip, port)
.useTransportSecurity()
.negotiationType(NegotiationType.TLS)
.sslContext(GrpcSslContexts.forClient()
.trustManager(new File("<path>/test.pem"))
.clientAuth(ClientAuth.REQUIRE)
.build())
.overrideAuthority("test")
.build();
试图使用CallCredentials和ClientInterceptor选项设置凭据,但没有一个起作用。服务器端用户名未收到。因此,出现io.grpc.StatusRuntimeException:UNAUTHENTICATED异常。
尝试过的CallCredentials:
OpenConfigGrpc.OpenConfigBlockingStub blockingStub = OpenConfigGrpc.newBlockingStub(channel).withCallCredentials(credentials);
public void applyRequestMetadata(MethodDescriptor<?, ?> methodDescriptor, Attributes attributes, Executor executor, final MetadataApplier metadataApplier) {
String authority = attributes.get(ATTR_AUTHORITY);
Attributes.Key<String> usernameKey = Attributes.Key.of("userId");
Attributes.Key<String> passwordKey = Attributes.Key.of("password");
attributes.newBuilder().set(usernameKey, username).build();
attributes.newBuilder().set(passwordKey, pasfhocal).build();
System.out.println(authority);
executor.execute(new Runnable() {
public void run() {
try {
Metadata headers = new Metadata();
Metadata.Key<String> usernameKey = Metadata.Key.of("userId", Metadata.ASCII_STRING_MARSHALLER);
Metadata.Key<String> passwordKey = Metadata.Key.of("password", Metadata.ASCII_STRING_MARSHALLER);
headers.put(usernameKey, username);
headers.put(passwordKey, pasfhocal);
metadataApplier.apply(headers);
} catch (Exception e) {
metadataApplier.fail(Status.UNAUTHENTICATED.withCause(e));
e.printStackTrace();
}finally{
logger.info("Inside CienaCallCredentials finally.");
}
}
});
}
尝试的拦截器:
OpenConfigGrpc.OpenConfigBlockingStubblockingStub = OpenConfigGrpc.newBlockingStub(channel).withInterceptors(interceptors);
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> methodDescriptor, CallOptions callOptions, Channel channel) {
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(channel.newCall(methodDescriptor, callOptions)) {
@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
callOptions.withCallCredentials(credentials);
Metadata.Key<String> usernameKey = Metadata.Key.of("usernId", Metadata.ASCII_STRING_MARSHALLER);
headers.put(usernameKey, username);
Metadata.Key<String> passwordKey = Metadata.Key.of("password", Metadata.ASCII_STRING_MARSHALLER);
headers.put(passwordKey, pasfhocal);
super.start(responseListener, headers);
}
};
}
非常感谢您的帮助,如果有人可以帮助您如何使用root.pem文件以及用户名和密码对gRPC进行身份验证。
预先感谢, Kishore