asp.ner core 5.0 Grpc雙向認證 和 restful api包裝 外加swagger啟用【VSCode創建】


關於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項目文件中添加元素項組

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>

添加必要的引用

dotnet add grpcclient.csproj package Grpc.Net.ClientFactory
dotnet add grpcclient.csproj package Google.Protobuf
dotnet add grpcclient.csproj package Grpc.Tools

客服端 代碼:

  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

dotnet add package Microsoft.AspNetCore.Grpc.HttpApi --version 0.1.0-alpha.20580.2

 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.

dotnet add package Microsoft.AspNetCore.Grpc.Swagger --version 0.1.0-alpha.20580.2

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);
        }
點擊並拖拽以移動

運行結果:

D:\Users\gavin\Documents\DotNetCoreSample\asp.netgrpccert\grpcclient>dotnet run
Greeting: Hello GreeterClient
http start................
{ "message": "Hello gavin" }

 文件下載: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM