gRPC 的驗證與授權在本質上是無狀態(stateless)的,因為每次連線都會被視為一個新的連線。在 .NET 中,我們通常透過 Authentication 和 Authorization 中介層來處理。
驗證資訊(如 JWT Bearer Token)會被放在 Metadata 中,這在 HTTP 協定中等同於 Headers。
// 加入驗證
builder.Services
.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
// JWT Token 的一些相關設定
});
// 加入授權
builder.Services.AddAuthorization(options =>
{
// 加入一些 Policy
options.AddPolicy("AdminOnly", policy =>
{
policy.RequireRole("admin");
});
});
...
// 啟用驗證與授權
app.UseAuthentication();
app.UseAuthorization();
...
一些服務端 Service
// 下面的標籤同原本的 .Net 的設定,針對不同用途加入不同的標籤
// 需要登入才能呼叫
[Authorize]
// 限定角色 admin
[Authorize(Policy = "AdminOnly")]
// 公開 API
[AllowAnonymous]
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
logger.LogInformation("The message is received from {Name}", request.Name);
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
var channel = GrpcChannel.ForAddress("https://localhost:7204");
var client = new ChatService.ChatServiceClient(channel);
// 在 Metadata 附加 JWT Token
var headers = new Metadata
{
{ "Authorization", "Bearer your-jwt-token" }
};
using var call = client.Chat(headers);