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的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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

posted on   dz45693  阅读(2308)  评论(1编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示