问题
I'm using protobuf-net.Grpc on a .NET Core server and trying to make calls from a .NET Framework (4.7.2.) gRPC Client. A full example is here: https://github.com/angelagyang/GRPCProtobufExample
Here is a snippet of my client:
var channelCreds = new SslCredentials(GetRootCertificates());
var channel = new Channel("localhost", 5001, channelCreds);
var greeter = channel.CreateGrpcService<IGreeterService>();
With this configuration, I get the error StatusCode="Unknown", Detail="Stream removed"...
when calling the server. I am able to connect to the server if I set ClientCertificateMode = ClientCertificateMode.NoCertificate
on the server. However, I want the server to require a client certificate and validate the certificate via thumbprint.
For example, in .NET Core, I can use Grpc.Net.Client to configure my channel like so:
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
var channel2 = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpHandler = handler
});
Is there any way to configure a client with certificate in .NET Framework like this? I'm pretty new to gRPC/.NET and would appreciate any suggestions!
回答1:
Solved and updated the original example: https://github.com/angelagyang/GRPCProtobufExample
You can configure a client certificate by creating a KeyCertificatePair to pass into SslCredentials. You will need the PEM encoded certificate chain and PEM encoded private key.
var keyCertPair = new KeyCertificatePair(File.ReadAllText($"{rootDir}/cert.pem"), File.ReadAllText($"{rootDir}/cert.key"));
var channelCreds = new SslCredentials(GetRootCertificates(), keyCertPair);
For testing purposes, I used the self-signed certificates here: https://github.com/grpc/grpc/tree/master/src/core/tsi/test_creds
When debugging, set GRPC_VERBOSITY = DEBUG
and GRPC_DEBUG = ALL
. This can help clear up vague error messages. For example, I realized that the server certificate I was using to configure HTTPS did not include localhost.
回答2:
From what I tried and made working, You can skip the effort of having to read both cert.pem
and cert.key
. Also the GetRootCertificate()
would work only if server systems are hosted in a well knows trusted website like google.com
or msdn.com
or the likes of it and localhost. More detailed answer can be found here and here
If we intend to use our own host DNS with SSL, Generating a Server certificate in pfx
assigned to your DNS and converting it to pem
for the client app is your way to go.
Using tools like openssl will help convert the certificate encoding.
openssl pkcs12 -in "<DiskLocationOfPfx>\ProjectName.pfx" -out "<TargetLocation>\certifcate.pem" -clcerts
Once you convert your server certificate to pem, You can use
var channelCreds = new SslCredentials(File.ReadAllText($"{rootDir}/cert.pem"));
var channel = new Channel("www.youdns.com", 5001, secureCredentials);
来源:https://stackoverflow.com/questions/62803003/how-can-i-connect-a-grpc-client-in-net-framework-with-a-secure-net-core-server