.net core gRPC与IdentityServer4集成认证授权

2023-12-21 11:32

本文主要是介绍.net core gRPC与IdentityServer4集成认证授权,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

随着.net core3.0的正式发布,gRPC服务被集成到了VS2019。本文主要演示如何对gRPC的服务进行认证授权。

分析

目前.net core使用最广的认证授权组件是基于OAuth2.0协议的IdentityServer4。而gRPC可以与ASP.NET Core Authentication一起使用来实现认证授权功能。本文将创建3个应用程序来完成gRPC的认证授权演示过程。
img_www.wityx.com

步骤

Ids4.Server
1.创建一个.net core的webapi
2.nuget引用最新的IdentityServer4的包
<PackageReference Include="IdentityServer4" Version="3.0.1" />

IdentityServer4相关配置,因为是演示所以很简单,生产场景大家根据实际情况配置。

namespace Ids4.Server
{public class Config{public static IEnumerable<IdentityResource> GetIdentityResources(){return new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Email(),};}public static IEnumerable<ApiResource> GetApis(){return new List<ApiResource>{new ApiResource("api", "Demo API"){ApiSecrets = { new Secret("secret".Sha256()) }}};}public static IEnumerable<Client> GetClients(){return new List<Client>{new Client{ClientId = "client",ClientSecrets = { new Secret("secret".Sha256()) },AllowedGrantTypes = GrantTypes.ClientCredentials,AllowedScopes = { "api" },},};}}
}
4. startup.cs 注入服务
services.AddIdentityServer().AddInMemoryApiResources(Config.GetApis()).AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryClients(Config.GetClients()).AddDeveloperSigningCredential(persistKey: false); 
5. startup.cs 配置http请求管道
app.UseIdentityServer();
6. 启动服务,使用PostMan进行调试,有返回结果表示服务创建成功
POST /connect/token HTTP/1.1
Host: localhost:5000
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=client1&client_secret=secret
{"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IlVyMmxuM2EwNGhWaGdDdWZTVTNtZVEiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1NzEzMDkwMTMsImV4cCI6MTU3MTMxMjYxMywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiYXBpIiwiY2xpZW50X2lkIjoiY2xpZW50Iiwic2NvcGUiOlsiYXBpIl19.X4pg9_FbPbWZl814XC0NYWTslfhMG4aXWEyXLrXhIojPJaL7Qvq9ieDF4S7x0psRcClwbwCg81hTrG3j2Cmcl0nzj_Ic7UY8MfN0dvAuy_fJdUf76TX0oOpir3SxgC8gnfaKyEoWmmbIyvwicWbKp9PP-EeTxG6-oMYn6PO22cwRVHDD28ZdEAq2DEkATOh9XPavoi9vGZhPQ1nviKL1K6tcYUGXSQbhWI9ISEqnTHqMX1xA_gcDIAplGvquXmtXdgyTsRoGolEtzDAYVH4sGUb1SpYx2nc8bgl6Qw27fhe0Uy9MR70kQMcEkCTdXLivjYjkuI9_quUyJHzdi5KgnQ","expires_in": 3600,"token_type": "Bearer","scope": "api"
}

本篇不对IdentityServer4做更多的讲解,大家可以参考官方文档了解更多。

Grpc.Server
1. 使用vs2019创建gRPC服务端。
2. 不用做任何更改,直接使用默认创建的gRPC服务
Grpc.Client
1. 创建一个控制台程序
2. 引入nuget安装包
<PackageReference Include="Google.Protobuf" Version="3.10.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.23.2" />
<PackageReference Include="Grpc.Tools" Version="2.24.0"><PrivateAssets>all</PrivateAssets><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

这3个核心包是客户端必备的,其中grpc.tools帮我们把proto文件转化成C#代码。

3. 创建Protos文件夹
4. 复制Grpc.Server项目Protos文件夹下的greet.proto文件到本项目的Protos文件夹
5. greet.proto文件右键设置gGRC Stub Classes为Client only。

img_www.wityx.com
也可以直接使用在项目文件里面代码设置如下:

<ItemGroup><Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
6. gRPC客户端访问服务端代码
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var response = client.SayHello(new HelloRequest { Name = "World" });
Console.WriteLine(response.Message);

启动gRPC服务端,在启动gRPC客户端控制台打印hello word表示成功。
img_www.wityx.com
identityServer接入gRPC是非常容易,和传统webapi差不多。

改造Grpc.Server支持IdentityServer4
1. 引入nuget包
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
2. startup.cs 注入服务,和IdentityServer4一样。
services.AddGrpc(x => x.EnableDetailedErrors = false);
services.AddAuthorization();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme).AddIdentityServerAuthentication(options =>{options.Authority = "http://localhost:5000";options.RequireHttpsMetadata = false;});
3. startup.cs 配置http请求管道
if (env.IsDevelopment())
{app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
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");});
});
4. 对需要授权的服务打标签[Authorize],可以打在类上也可以打在方法上
[Authorize]
public class GreeterService : Greeter.GreeterBase
{
}

这个时候我们启动Grpc.Client访问Grpc.Server服务
www.wityx.com
发现报错401。说明此服务需要携带令牌才能访问。

改造Grpc.Client携带令牌访问
//获取token可以直接使用HttpClient来获取,这里使用IdentityModel来获取token
var httpClient = new HttpClient();
var disco = await httpClient.GetDiscoveryDocumentAsync("http://localhost:5000");
if (!disco.IsError)
{var token = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest(){Address = disco.TokenEndpoint,ClientId = "client",ClientSecret = "secret"});var tokenValue = "Bearer " + token.AccessToken;var metadata = new Metadata{{ "Authorization", tokenValue }};var callOptions = new CallOptions(metadata);var channel = GrpcChannel.ForAddress("https://localhost:5001");var client = new Greeter.GreeterClient(channel);var response = client.SayHello(new HelloRequest { Name = "World" }, callOptions);Console.WriteLine(response.Message);
}

执行程序返回hello world表示成功。

传统调用webapi把token放到Header头的Authorization属性里面,grpc是放到Metadata里面,调用方法的时候传入CallOptions。使用上大同小异。

后记

目前gRPC各个语言的支持都已经很完善,因为跨语言,性能更高的特性非常适合做内网的通信。笔者也将继续对gRPC进行跟进,会尝试将部分的内部服务改造成gRPC,关于gRPC的相关问题也可以留言大家一起讨论。
源代码地址:github

这篇关于.net core gRPC与IdentityServer4集成认证授权的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/519818

相关文章

在Spring Boot中集成RabbitMQ的实战记录

《在SpringBoot中集成RabbitMQ的实战记录》本文介绍SpringBoot集成RabbitMQ的步骤,涵盖配置连接、消息发送与接收,并对比两种定义Exchange与队列的方式:手动声明(... 目录前言准备工作1. 安装 RabbitMQ2. 消息发送者(Producer)配置1. 创建 Spr

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

SpringBoot集成LiteFlow工作流引擎的完整指南

《SpringBoot集成LiteFlow工作流引擎的完整指南》LiteFlow作为一款国产轻量级规则引擎/流程引擎,以其零学习成本、高可扩展性和极致性能成为微服务架构下的理想选择,本文将详细讲解Sp... 目录一、LiteFlow核心优势二、SpringBoot集成实战三、高级特性应用1. 异步并行执行2

使用Python进行GRPC和Dubbo协议的高级测试

《使用Python进行GRPC和Dubbo协议的高级测试》GRPC(GoogleRemoteProcedureCall)是一种高性能、开源的远程过程调用(RPC)框架,Dubbo是一种高性能的分布式服... 目录01 GRPC测试安装gRPC编写.proto文件实现服务02 Dubbo测试1. 安装Dubb

MySQL 用户创建与授权最佳实践

《MySQL用户创建与授权最佳实践》在MySQL中,用户管理和权限控制是数据库安全的重要组成部分,下面详细介绍如何在MySQL中创建用户并授予适当的权限,感兴趣的朋友跟随小编一起看看吧... 目录mysql 用户创建与授权详解一、MySQL用户管理基础1. 用户账户组成2. 查看现有用户二、创建用户1. 基

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

使用vscode搭建pywebview集成vue项目实践

《使用vscode搭建pywebview集成vue项目实践》:本文主要介绍使用vscode搭建pywebview集成vue项目实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录环境准备项目源码下载项目说明调试与生成可执行文件核心代码说明总结本节我们使用pythonpywebv