我需要使用gRPC进行双向流,其中客户端是.Net Framework项目,由于遗留问题,无法升级到.NET5+。
在阅读微软文档时,我可以看到应该使用WinHttpHandler(https://learn.microsoft.com/en-us/aspnet/core/grpc/netstandard?view=aspnetcore-5.0)。
但我似乎在使用 SSL 进行此设置时遇到问题,有人建议如何解决此问题吗?
我收到以下错误:
“InvalidOperationException:GrpcChannel 不支持具有非空参数的 SslCredentials。GrpcChannel 使用 HttpClient 进行 gRPC 调用,HttpClient 自动从操作系统证书存储加载根证书。应在 HttpClient 上配置客户端证书。请参阅 https:// aka.ms/aspnet/grpc/certauth 了解详细信息。”
我的服务器设置如下:
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'''
客户端使用此设置:
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)
它是用 F# 编写的,但与此 C# 代码类似(如果参考有助于提高可读性)。 如何为 gRPC 启用服务器端 SSL?
可能按照以下思路(草稿)应该有效:
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)
与 @CaringDev 所写的问题相同,但针对 C# :
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using Grpc.Net.Client;
namespace IntegrationTests
{
public class Class
{
public void Method()
{
var clientCert = new X509Certificate();
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(clientCert);
handler.ServerCertificateCustomValidationCallback = delegate { return true; };
var client = new HttpClient(handler);
var channelOptions = new GrpcChannelOptions() { HttpClient = client };
var channel = Grpc.Net.Client.GrpcChannel.ForAddress("http://127.0.0.1:5001", channelOptions);
}
public Or_GrpcCore_InsteadOf_GrpcNetClient_Namespace()
{
/* For HTTP 1 / 1.1 Use Obsolete "Grpc.Core" */
var channel = new Grpc.Core.Channel(host: "localhost", port: 5001,
ChannelCredentials.Insecure,
new ChannelOption[]
{
new ChannelOption(global::Grpc.Core.ChannelOptions.MaxReceiveMessageLength, int.MaxValue)
});
}
}
}