I need to use gRPC for bi-directional streaming, where the client is a .Net Framework project, which due to legacy stuff, can't be upgraded to .NET5 .
When reading microsoft documentation, i can see that the WinHttpHandler should be used (https://docs.microsoft.com/en-us/aspnet/core/grpc/netstandard?view=aspnetcore-5.0).
But i seem to have an issue using SSL with this setup, does anybody have a suggestion to what can be done to solve this issue?
I get the following error:
"InvalidOperationException: SslCredentials with non-null arguments is not supported by GrpcChannel. GrpcChannel uses HttpClient to make gRPC calls and HttpClient automatically loads root certificates from the operating system certificate store. Client certificates should be configured on HttpClient. See https://aka.ms/aspnet/grpc/certauth for details."
My server is setup with the following setup:
let cacert = File.ReadAllText(@"ca.crt");
let servercert = File.ReadAllText(@"server.crt");
let serverkey = File.ReadAllText(@"server.key");
let certificatePair = new KeyCertificatePair(servercert, serverkey);
let certList = new System.Collections.Generic.List<KeyCertificatePair>()
certList.Add(certificatePair)
let server = new Server()
server.Services.Add(EventSubscriberService.EventSubscriberServiceMethodBinder.BindService(new EventSubscriber()))
server.Ports.Add(new ServerPort("localhost", 5001,SslServerCredentials(certList,cacert,false)))
|> ignore'''
And the client uses this setup:
let cacert = File.ReadAllText(@"ca.crt");
let clientcert = File.ReadAllText(@"client.crt");
let clientkey = File.ReadAllText(@"client.key");
let ssl = new SslCredentials(cacert, new KeyCertificatePair(clientcert, clientkey))
let channelOptions = GrpcChannelOptions()
channelOptions.HttpHandler <- new WinHttpHandler()
channelOptions.Credentials <- ssl
let channel = GrpcChannel.ForAddress("http://127.0.0.1:5001",channelOptions)
It is written in F#, but resembles this C# code, if reference helps readability. How to enable server side SSL for gRPC?
CodePudding user response:
Probably something along the following lines (rough draft) should work:
open System.Net.Http
open Grpc.Net.Client
open System.Security.Cryptography.X509Certificates
let clientCert = new X509Certificate() // create according to your needs
let handler = new HttpClientHandler()
handler.ClientCertificates.Add(clientCert) |> ignore
// insecure, check your custom server cert
handler.ServerCertificateCustomValidationCallback <- fun msg cert chain e -> true
let client = new HttpClient(handler)
let channelOptions = GrpcChannelOptions(HttpClient = client)
let channel = GrpcChannel.ForAddress("http://127.0.0.1:5001", channelOptions)