關於grpc 我以前的文章 .Net Core3.0使用gRPC 和IdentityServer4 已經很向詳細了, 關於http的雙向認證 也已經有了, 大家可以參考 asp.net 5.0 https的雙向認證(windows和ubuntu) ,今天主要試一下 在vccode 里面怎么完成全部的操作,證書還是用asp.net 5.0 https的雙向認證(windows和ubuntu) 里面的, 在。net里面也有httpApi。本文主要是實現
1.gprc 客服端 和服務端 實現雙向認證
2.普通的js 可以訪問grpc服務, 這里采用httpapi 來包裝【以前在go里面沒有完全實現,在go里面用gateway后,grprc 客戶端 和gateway 都只能用http協議, 不能像本文中 兼容https 和http】
Grpc Server
1.創建grpc server
創建結果如圖:
2.現在我們創建grpcclient【 控制台程序】, 然后把cert文件夾拷貝到項目文件夾中,cert包含server.pfx和client.pfx證書
3. grpcserver項目需要用到server.pfx證書,grpcclient需要用到client.pfx證書 ,我習慣用相對目錄,所以把證書拷貝到輸出目錄
用記事本修改grpcserver.csproj文件,添加
<ItemGroup> <None Update="cert\server.pfx"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> </ItemGroup>
同理grpcclient.csproj 也要修改
<ItemGroup> <None Update="cert\client.pfx"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> </ItemGroup>
4.修改grpcserver的Program.cs的CreateHostBuilder方法 需要添加引用:
using System.Security.Cryptography.X509Certificates; using Microsoft.AspNetCore.Server.Kestrel.Https; using System.Security.Authentication; //////////////////////////////////////////// public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); webBuilder.ConfigureKestrel(kerstrel => { kerstrel.ConfigureHttpsDefaults(https => { var serverPath = AppDomain.CurrentDomain.BaseDirectory + "cert\\server.pfx"; var serverCertificate = new X509Certificate2(serverPath, "123456789"); https.ServerCertificate = serverCertificate; https.ClientCertificateMode = ClientCertificateMode.AllowCertificate; https.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls | SslProtocols.None | SslProtocols.Tls11; https.ClientCertificateValidation = (cer, chain, error) => { return chain.Build(cer); }; }); }); });
5 注意系統的版本, 我在win7下面 有如下錯誤HTTP/2 over TLS is not supported on Windows versions earlier than Windows 10 and Windows Server 2016 due to incompatible ciphers or missing ALPN support.現在修改grpcclient,將服務端的Protos/greet.proto拷貝到客戶端Protos/greet.proto下,並在grpcclient.csproj項目文件中添加元素項組
客服端 代碼:
static void Main(string[] args) { var handler = new HttpClientHandler() { SslProtocols = SslProtocols.Tls12, ClientCertificateOptions = ClientCertificateOption.Manual, ServerCertificateCustomValidationCallback = (message, cer, chain, errors) => { return chain.Build(cer); } }; var path = AppDomain.CurrentDomain.BaseDirectory + "cert\\client.pfx"; var crt = new X509Certificate2(path, "123456789"); handler.ClientCertificates.Add(crt); var channel = GrpcChannel.ForAddress("https://localhost:5001",new GrpcChannelOptions{HttpHandler=handler}); var client = new Greeter.GreeterClient(channel); var reply = client.SayHello( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); }
運行結果:
gRPC HTTP API
1.在grpcserver 添加 Microsoft.AspNetCore.Grpc.HttpApi
2.Startup.cs 添加 ConfigureServices方法 添加 services.AddGrpcHttpApi();
3.添加 google/api/http.proto ,google/api/annotations.proto和 google/protobuf/descriptor.proto 到 grpcserver【注意google 文件和Protos文件夾同級別】
4.修改greet.proto 如下: 主要是添加 import "google/api/annotations.proto"; 引用 和 api定義 option (google.api.http) = { get: "/v1/greeter/{name}" };
syntax = "proto3"; import "google/api/annotations.proto"; option csharp_namespace = "grpcserver"; package greet; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) { option (google.api.http) = { get: "/v1/greeter/{name}" }; } } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings. message HelloReply { string message = 1; }
啟用 Swagger/OpenAPI
1.添加引用 Microsoft.AspNetCore.Grpc.Swagger.
2.修改 Startup.cs 文件
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; namespace grpcserver { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddGrpc(); services.AddGrpcHttpApi(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); }); services.AddGrpcSwagger(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGrpcService<GreeterService>(); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); }); }); } } }
運行服務端:訪問 https://localhost:5001/swagger/index.html
修改grpcserver 讓他支持https 雙向認證 同時也支持普通http 請求
修改grpcserver的Program.cs的CreateHostBuilder 方法如下:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); webBuilder.ConfigureKestrel(kerstrel => { kerstrel.Listen(IPAddress.Any, 5000, o => o.Protocols = HttpProtocols.Http1AndHttp2); kerstrel.Listen(IPAddress.Any, 5001, listenOptions => { var serverPath = AppDomain.CurrentDomain.BaseDirectory + "cert\\server.pfx"; var serverCertificate = new X509Certificate2(serverPath, "123456789"); var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions() { ClientCertificateMode = ClientCertificateMode.AllowCertificate, SslProtocols = System.Security.Authentication.SslProtocols.Tls12, //用chain.Build驗證客戶端證書 ClientCertificateValidation = (cer, chain, error) => { return chain.Build(cer); }, ServerCertificate = serverCertificate }; listenOptions.UseHttps(httpsConnectionAdapterOptions); }); }); });
修改grpcclient的調用:
static void Main(string[] args) { var handler = new HttpClientHandler() { SslProtocols = SslProtocols.Tls12, ClientCertificateOptions = ClientCertificateOption.Manual, ServerCertificateCustomValidationCallback = (message, cer, chain, errors) => { return chain.Build(cer); } }; var path = AppDomain.CurrentDomain.BaseDirectory + "cert\\client.pfx"; var crt = new X509Certificate2(path, "123456789"); handler.ClientCertificates.Add(crt); var channel = GrpcChannel.ForAddress("https://localhost:5001",new GrpcChannelOptions{HttpHandler=handler}); var client = new Greeter.GreeterClient(channel); var reply = client.SayHello( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); /// Console.WriteLine("http start................"); var httphandler = new HttpClientHandler(); httphandler.ServerCertificateCustomValidationCallback=HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; var httpclient=new HttpClient(httphandler); var ret= httpclient.GetStringAsync("http://localhost:5000/v1/greeter/gavin").Result; Console.WriteLine(ret); } 點擊並拖拽以移動
運行結果:
文件下載:https://download.csdn.net/download/dz45693/14015673 https://github.com/dz45693/asp.netgrpccert.git
參考
https://docs.microsoft.com/en-us/aspnet/core/grpc/httpapi?view=aspnetcore-5.0