一.開頭聊騷
本文算是對於 ASP.NET Core 3.0 gRPC 研究性學習的最后一篇了,以后在實際使用中,可能會發一些經驗之文。本文主要講 ASP.NET Core 本身的認證授權和gRPC接入,認證方式采用目前主流的 JWT 結合 IdentityServer4。
二.服務端配置
我們首先需要在服務端配置認證和授權。gRPC基於此文的Demo來開始: ASP.NET Core 3.0 使用gRPC ,IdentityServer 基於此文Demo: https://www.cnblogs.com/stulzq/p/7509648.html 。
配置
1.首先啟動 IdentityServer4 地址為:http://localhost:5000
2.為gRPC項目安裝Jwt組件:Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 3.0.0
3.為gRPC項目配置認證和授權服務
在 Startup 類的 ConfigureServices 方法中,配置如下代碼
services.AddAuthorization(options =>
{
options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
{
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.RequireClaim("sub");
});
});
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.Audience = "grpc1";
});
4.啟用認證授權中間件
在 Startup 類的 Configure 方法中,配置如下代碼
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
請務必注意中間件順序
5.為gRPC服務啟用授權
我們在 LuCatService 的 SuckingCat 方法上,加上 [Authorize]
特性,就和在MVC中一樣。
測試
運行客戶端調用服務端來進行測試,發現服務端返回了授權失敗,客戶端同樣獲得了錯誤。這證明我們的服務端配置是沒有問題的
三.客戶端配置
配置
客戶端首先需要從 IdentityServer 申請 Token,然后在調用 gRPC 服務時傳遞過去,這和 HTTP Api 調用一樣。
1.客戶端項目安裝組件 IdentityModel
獲得基於 HttpClient 的和 IdentityServer 的交互的封裝。
2.獲取Token
// discover endpoints from metadata
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
// request token
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "ro.client",
ClientSecret = "secret",
UserName = "alice",
Password = "password",
Scope = "grpc1"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
Console.WriteLine("\n\n");
3.為 gRPC 客戶端請求設置 Token
和 HTTP Api 調用一樣,gRPC也是放在頭部的
var headers = new Metadata {{"Authorization", $"Bearer {tokenResponse.Json["access_token"]}"}};
var catClient = new LuCat.LuCatClient(channel);
var catReply = await catClient.SuckingCatAsync(new Empty(), headers);
主要就是在調用 SuckingCatAsync
方法時,傳入了header。
測試
可以看到成功的進行了調用。
四.結束
本文所用代碼地址:Demo
gRPC in Asp.Net Core :官方文檔