Server端
StartUp类:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using IdentityServer4.AccessTokenValidation; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace GRPCTokenServer { 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.AddHttpContextAccessor(); services.AddGrpc(options => { options.EnableDetailedErrors = true; }); services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { options.Authority = "http://localhost:54311/"; options.RequireHttpsMetadata = false; options.ApiName = "identity"; options.SaveToken = true; }); services .AddControllers(); } // 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.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { // 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 endpoints.MapGrpcService<GreeterService>(); //endpoints.MapControllers(); }); } } }
Service
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Grpc.Core; using Microsoft.AspNetCore.Authorization; namespace GRPCTokenServer { [Authorize(AuthenticationSchemes = "Bearer")] public class GreeterService : Greeter.GreeterBase { public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) {
var user = context.GetHttpContext().User; return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); } } }
proto
syntax = "proto3"; option csharp_namespace = "GRPCTokenServer"; package Greet; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings. message HelloReply { string message = 1; }
Client
using Grpc.Core; using Grpc.Net.Client; using GRPCTokenServer; using System; using System.Net.Http; namespace GRPCTokenClient { class Program { static async System.Threading.Tasks.Task Main(string[] args) { // AppContext.SetSwitch( //"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", //true); // var httpClient = new HttpClient(); // // The port number(50051) must match the port of the gRPC server. // httpClient.BaseAddress = new Uri("http://localhost:50051"); // var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient); // HttpClient httpClient = new HttpClient(); //httpClient.BaseAddress = new Uri("https://localhost:50051"); //var result = await httpClient.PostAsync("api/token", new { Email = "admin@contract.com", Password = "12345678" }.AsJson()); var tokenValue = "Bearer " + "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk4OTIzRkRERTkxODJDOURERjRGQzZCQzNBMEI1RDUzNDNFNkM4QjEiLCJ0eXAiOiJKV1QiLCJ4NXQiOiJtSklfM2VrWUxKM2ZUOGE4T2d0ZFUwUG15TEUifQ.eyJuYmYiOjE1NjEyNjEwODUsImV4cCI6MTU2MjI2MTA4NSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1NDMxMSIsImF1ZCI6ImlkZW50aXR5IiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiI0NzczYzUzMi0wMDg1LTQwZGUtYTllNy1iZTNlMjBhNjdlOTQiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiMTU5MDE0MDIzODIiLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6Iks0RlE2Sk1TNEZPUzROR1Q2TE9UVFlJR1ZDRTZRQlRVIiwidXNlcmlkIjoiNDc3M2M1MzItMDA4NS00MGRlLWE5ZTctYmUzZTIwYTY3ZTk0IiwidXNlcm5hbWUiOiIxNTkwMTQwMjM4MiJ9.pSEkPwyRMNeDYd6ONR0xjJMfhFhOgZB_gcr0fa7NP8dAnPfuf4aW0xIzNsAp6NGn91fu9vbV5gSEbTUghRfzKemEcPwIDaeho1oYvV-xFRWBBo4JFBx5FcB-kVdy4TeFCTu1nTIb0MUqmkgk40HFngmK7jW9epAu2m1YYvyvweqoe5cS4eHcEMun4lSOlJwoCmL-V1DW_LQb8LojrBUjn2mz3f0yAlUWIA_vi_Z37QX60Sg-BMtlrH0fdaJuypNdRtlWp6qvNEZgZ496wIjHnSCUr15Z6AbqQfa2XTBI16pLj96HTeTjkxGR0XmoCaRmXWiTeOg0nFq5pZ8dDoJOIg"; var metadata = new Metadata { { "Authorization", tokenValue } }; CallOptions callOptions = new CallOptions(metadata); var channel = new Channel("localhost:50051", SslCredentials.Insecure); var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync( new HelloRequest { Name = "GreeterClient" }, callOptions); Console.WriteLine("Greeting: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } }
https://github.com/cysnet/Secure_gRpc
https://github.com/cysnet/GRPC_IdentityServer4
https://damienbod.com/2019/03/06/security-experiments-with-grpc-and-asp-net-core-3-0/