.Net6 微服务之Ocelot+IdentityServer4入门看这篇就够了
前言
.Net 6 使用 Consul 实现服务注册与发现 看这篇就够了
.Net6 使用 Ocelot + Consul 看这篇就够了
.Net6 微服务之Polly入门看这篇就够了
书接上文,本文将继续建立在 .Net6 使用 Ocelot + Consul 看这篇就够了文章中的项目基础上来进行Ocelot与IdentityServer4的介绍。项目也都比较简单,不熟悉的同学可以去翻翻我之前的文章,相信都能一看就会。其实网上关于Id4的文章还是比较多了,本文只会对其进行简单的介绍,不会过多深究,感兴趣的同学可以自行研究。然后本文只是个人学习与分享,不喜勿喷,谢谢!
什么是IdentityServer4?

IdentityServer 是一个 OpenID Connect 提供者—— 它实现了 OpenID Connect 和 OAuth 2.0 协议。
- User:用户
- Client:客户端
- Resources:Identity Data(身份数据)、Apis
- Identity Server:认证授权服务器
- Token:Access Token(访问令牌)和 Identity Token(身份令牌)
基于以上我们先来简单了解 OAuth2.0 与 OpenID Connect是个什么东西,它们能干些什么?解决了哪些问题以及我们怎么使用它们?我们需要带着一些问题来学习新东西才会事半功倍。
OAuth2
OAuth是一个开放授权标准,是一个授权协议,并不是认证协议,它无法提供完善的身份认证功能,它解决的问题是授权 。本文介绍的版本为2.0。
它允许用户让第三方应用访问该用户在某服务的特定私有资源,但是不提供账号密码给第三方用户。然后它是通过给用户提供Token(令牌)的方式来访问他们存放在特定服务商上的数据,每一个Token授权一个特定的网站内访问特定的资源,而不是一味的放开所有内容。
下面是OAuth 2.0的运行流程图以及相关介绍:
Client:客户端
Resource Owner:资源所有者
Authorization Server:认证服务器,即服务提供商专门用来处理认证的服务器。
Resource Server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
简单了解之后,我们可以发现B步骤是关键,即用户怎么才能给客户端授权。只有拿到这个授权之后,客户端才能获取到令牌,从而凭借令牌获取资源。所以OAuth2.0为此定义了四种授权方式,如下:
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
这里我们只做简单了解,就不展开了,感兴趣的同学可以参考官网或者大佬的文章。
OpenId Connect(OIDC)
OpenId Connect = OIDC = Authentication + Authorization + OAuth2.0
OIDC是一个基于OAuth2协议的身份认证标准协议,解决的问题是用户认证,而不关心授权。
我们都知道OAuth2是一个授权协议,它无法提供完善的身份认证功能,所以OIDC干的活就是使用OAuth2的授权服务器来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且可以适用于各种类型的客户端(比如服务端应用,移动APP,JS应用),且完全兼容OAuth2,也就是说你搭建了一个OIDC的服务后,也可以当作一个OAuth2的服务来用。
下面是OIDC的运行流程图以及相关介绍:
- EU:End User:一个人类用户。
- RP:Relying Party ,用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方;
- OP:OpenID Provider,有能力提供EU认证的服务(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息;
- ID Token:JWT格式的数据,包含EU身份认证的信息。
- UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用Access Token访问时,返回授权用户的信息,此接口必须使用HTTPS。
- AuthN:Authentication 认证
- AuthZ:Authorization 授权

- RP发送一个认证请求给OP;
- OP对EU进行身份认证,然后提供授权;
- OP把ID Token和Access Token(需要的话)返回给RP;
- RP使用Access Token发送一个请求UserInfo EndPoint;
- UserInfo EndPoint返回EU的Claims。
注意这里面RP发往OP的请求,是属于Authentication类型的请求,虽然在OIDC中是复用OAuth2的Authorization请求通道,但是用途是不一样的,且OIDC的AuthN请求中scope参数必须要有一个值为的openid的参数,用来区分这是一个OIDC的Authentication请求,而不是OAuth2的Authorization请求。
然后我们简单了解下 ID Token
ID Token
OIDC对OAuth2最主要的扩展就是提供了ID Token.
ID Token是一个安全令牌,是一个授权服务器提供的包含用户信息(由一组Cliams构成以及其他辅助的Cliams)的JWT格式的数据结构。
ID Token的主要构成部分如下(使用OAuth2流程的OIDC)。
- iss = Issuer Identifier:必须。提供认证信息者的唯一标识。一般是一个https的url(不包含querystring和fragment部分)。
- sub = Subject Identifier:必须。iss提供的EU的标识,在iss范围内唯一。它会被RP用来标识唯一的用户。最长为255个ASCII个字符。
- aud = Audience(s):必须。标识ID Token的受众。必须包含OAuth2的client_id。
- exp = Expiration time:必须。过期时间,超过此时间的ID Token会作废不再被验证通过。
- iat = Issued At Time:必须。JWT的构建的时间。
- auth_time = AuthenticationTime:EU完成认证的时间。如果RP发送AuthN请求的时候携带max_age的参数,则此Claim是必须的。
- nonce:RP发送请求的时候提供的随机字符串,用来减缓重放攻击,也可以来关联ID Token和RP本身的Session信息。
- acr = Authentication Context Class Reference:可选。表示一个认证上下文引用值,可以用来标识认证上下文类。
- amr = Authentication Methods References:可选。表示一组认证方法。
- azp = Authorized party:可选。结合aud使用。只有在被认证的一方和受众(aud)不一致时才使用此值,一般情况下很少使用。
这里只是简单介绍,感兴趣的同学可以去官网了解更多。下面开始实操。
抛玉引砖 O(∩_∩)O !
项目准备
.Net 6
Visual Studio 2022
https://github.com/fengzhonghao8-24/Consul.Ocelot
搭建IdentityServer4项目
我们基于上篇项目来新增一个IdentityServer4Center项目
引入IdentityServer4 Nuget包,然后新增一个配置文件 Config.cs 配置模拟数据
定义API范围
//https://www.cnblogs.com/Mamba8-24
public static IEnumerable<ApiScope> ApiScopes =>
new List<ApiScope>
{
new ApiScope("serviceA"),
new ApiScope("serviceB")
};
定义API资源
//https://www.cnblogs.com/Mamba8-24
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>()
{
new ApiResource("serviceA","serviceA"){ Scopes={ "serviceA" } },
new ApiResource("serviceB","serviceB"){ Scopes={ "serviceB" } }
};
}
定义客户端
//https://www.cnblogs.com/Mamba8-24
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client{
ClientId="web_client",//客户端唯一标识
ClientName="AuthCenter",
//AllowedGrantTypes=new List<string>{ "paas_password", "paas_auth_code", "client_credentials"},
AllowedGrantTypes=GrantTypes.ClientCredentials,
ClientSecrets=new[]{new Secret("Mamba24".Sha256()) },//客户端密码,进行了加密
AccessTokenLifetime=3600,
AllowedScopes=new List<string>//允许访问的资源
{
"serviceA",
"serviceB"
},
Claims=new List<ClientClaim>(){
new ClientClaim(IdentityModel.JwtClaimTypes.Role,"Admin"),
new ClientClaim(IdentityModel.JwtClaimTypes.NickName,"Mamba24"),
}
}
};
}
然后在Program.cs进行DI
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryClients(Config.GetClients())//Client模式
.AddInMemoryApiScopes(Config.ApiScopes)//作用域
.AddInMemoryApiResources(Config.GetApiResources());//资源
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.UseIdentityServer();//使用Id4
然后我们将项目run起来看看效果:
使用Postman请求Token
这里请求参数内容都是在定义客户端的时候定义好的,只需要注意 grant_type 这里为 client_credentials 客户端模式,如果在定义客户端的时候AllowedGrantTypes 配置的是 ResourceOwnerPassword 则 grant_type 为 password,具体参考GrantTypes.cs。
OK,IdentityServer4Center项目搭建完成。接下来我们将网关与 IdentityServer4 结合使用。
Ocelot结合dentityServer4
接下来会模拟通过集成了Id4的网关来访问ServiceA或者ServiceB服务以达到演示效果。
首先我们在Gateway项目中装两个包
然后在ocelot.json 文件中增加Id4鉴权资源
{
"Routes": [
{
"DownstreamPathTemplate": "/{url}", //下游(转发的服务地址模板)
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5550
}
],
"UpstreamPathTemplate": "/ocelot/{url}", //上游(请求路径模板)
"UpstreamHttpMethod": [ "Get", "Post" ],
//鉴权
"AuthenticationOptions": {
"AuthenticationProviderKey": "serviceA", //指定一个key
"AllowedScopes": [ "serviceA" ] //id4的作用域名称
}
},
{
"DownstreamPathTemplate": "/{url}", //下游(转发的服务地址模板)
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5551
}
],
"UpstreamPathTemplate": "/ocelotB/{url}", //上游(请求路径模板)
"UpstreamHttpMethod": [ "Get", "Post" ],
//鉴权
"AuthenticationOptions": {
"AuthenticationProviderKey": "serviceB", //指定一个key
"AllowedScopes": [ "serviceB" ] //id4的作用域名称
}
}
]
}
然后在 Program.cs进行配置
由于Ocelot网关默认集成了Id4所以我们只需要在之前代码的基础上增加对需要进行鉴权服务的配置。
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
var authenticationProviderKey = "serviceA";
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(authenticationProviderKey, options =>
{
options.Authority = "http://localhost:5269";//id4服务地址
options.ApiName = "serviceA";//id4 api资源里的apiname
options.RequireHttpsMetadata = false; //不使用https
options.SupportedTokens = SupportedTokens.Both;
});
authenticationProviderKey = "serviceB";
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(authenticationProviderKey, options =>
{
options.Authority = "http://localhost:5269";//id4服务地址
options.ApiName = "serviceB";//id4 api资源里的apiname
options.RequireHttpsMetadata = false; //不使用https
options.SupportedTokens = SupportedTokens.Both;
});
builder.Services.AddOcelot().AddConsul();
到这里我们就差不多简单的配置完成了,接下来看看效果。
同时启动Gateway,IdentityServer4Center,ServiceA,ServiceB项目
网关项目启动地址端口为5055
我们现在直接通过网关来请求ServiceA服务的接口(不带token) http://localhost:5055/ocelot/testA
结果出现401,达到预期效果
接着我们带上token再次访问
返回200,请求成功。
然后接下来我们给ServiceB 服务单独增加授权认证,模拟请求绕过网关直接访问下游服务。
Program.cs

代码很简单,我们单独访问ServiceB看看效果
结果出现 401
然后我们拿着token去访问
可以正常访问
到此,我们基于 客户端模式(client credentials)模拟的一个简单的示例就完成了,这个模式没有用户参与,也就是说此模式只适用于在资源或者资源服务器不属于某个人或者用户,没有资源所有者对资源进行控制,但是客户端需要访问这个受保护资源的情况下。
接下来我们可以尝试在客户端模式(client credentials)下访问Id4的身份认证资源(对应用户)
我们稍微调整代码
Config.cs

模拟用户
Program.cs
然后我们先在 client credentials 客户端模式 下请求token,去访问Id4的身份认证资源。
出现 403异常,所以在这个模式下这样的请求是不合理的,这也就验证了我们上述所说。
接下来我们可以尝试模拟 密码模式(resource owner password credentials)这个模式会有用户参与
然后再次访问Id4的身份认证资源
OK,成功拿到资源信息。
结尾
由于文章篇幅有限,涉及到知识内容也不是很深入,感兴趣的同学可以自行研究。
然后本文都是基于我的个人理解,然后也有参考官网以及大佬的文章和视频,文章如有什么不妥的地方欢迎指正,共同进步。后续有时间还会继续学习相关技术知识,欢迎Star与关注。谢谢!
参考链接
https://www.bilibili.com/video/BV16b411k7yM?p=5
https://identityserver4docs.readthedocs.io/zh_CN/latest/index.html
https://www.cnblogs.com/linianhui/category/929878.html
源码地址
https://github.com/fengzhonghao8-24/Consul.Ocelot.IdentityServer4.git
.Net6 微服务之Ocelot+IdentityServer4入门看这篇就够了的更多相关文章
- React入门看这篇就够了
摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所有. React 背景介绍 React 入门实例教程 React 起源于 ...
- [转帖]Zookeeper入门看这篇就够了
Zookeeper入门看这篇就够了 https://my.oschina.net/u/3796575/blog/1845035 Zookeeper是什么 官方文档上这么解释zookeeper,它是一个 ...
- [转]React入门看这篇就够了
摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所有. React 背景介绍 React 入门实例教程 React 起源于 ...
- .Net6 微服务之Polly入门看这篇就够了
前言 O(∩_∩)O 大家好!书接上文,本文将会继续建立在 .Net6 使用 Ocelot + Consul 看这篇就够了 项目的基础上进行Polly的介绍,然后这篇文章只是个人学习与分享,不喜勿喷, ...
- .NET Core实战项目之CMS 第五章 入门篇-Dapper的快速入门看这篇就够了
写在前面 上篇文章我们讲了如在在实际项目开发中使用Git来进行代码的版本控制,当然介绍的都是比较常用的功能.今天我再带着大家一起熟悉下一个ORM框架Dapper,实例代码的演示编写完成后我会通过Git ...
- ZooKeeper 入门看这篇就够了
什么是 ZooKeeper? ZooKeeper 是一个分布式的,开放源码的分布式应用程序协同服务.ZooKeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原 ...
- Zookeeper入门看这篇就够了!!
Zookeeper是什么 官方文档上这么解释zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名 ...
- EFCore 6.0入门看这篇就够了
前言 作为一直在dotNet行业耕耘的码农,这几年在大大小小项目中也涉及到了许多ORM框架,比如:EFCore,Dapper,NHibernate,SqlSugar等等,这些ORM都有各自的优缺点,大 ...
- Storm入门,看这篇就够了
部分一:Srorm 简介 1.1 Storm是实时的数据流,Hadoop是批量离线数据 起源背景 Twitter 开源的一个类似于Hadoop的实时数据处理框架 Storm是由Nathan Marz ...
- Zookeeper入门看这篇就够了
https://blog.csdn.net/java_66666/article/details/81015302
随机推荐
- EXACT函数
EXACT函数:EXACT函数是一个文本函数,通过这个函数可以将不同的字符串进行对比,通常用于信息核对. EXACT函数的功能:比较两个字符串是否一致,返回不同的结果. EXACT函数的语法结构:EX ...
- 微信小程序地区和location_id对应关系
点击查看代码 location_list = [ {'location_id': '101010100', 'location_name': ['北京', '北京', '北京']}, {'locati ...
- AcWing786.第k个数
题目描述 给定一个长度为 \(n\) 的整数数列,以及一个整数 \(k\),请用快速选择算法求出数列从小到大排序后的第 \(k\) 个数. 输入格式 第一行包含两个整数 \(n\) 和 \(k\). ...
- 1+X Web初级笔记查漏补缺+练习题
学习笔记: position:relative是相对定位,是相对于自身位置移动,但是占据原有空间 absolute是绝对定位,原有空间不保留会被其他元素挤占 绝对定位 absolute不占位置完全浮动 ...
- [常用工具] Python视频处理库VidGear使用指北
VidGear是一个高性能的Python视频处理库,它在预载多个专业视频图像处理库的基础上,如OpenCV.FFmpeg.ZeroMQ.picamera.starlette.yt_dlp.pyscre ...
- 从Babel开始认识AST抽象语法树
前言 AST抽象语法树想必大家都有听过这个概念,但是不是只停留在听过这个层面呢.其实它对于编程来讲是一个非常重要的概念,当然也包括前端,在很多地方都能看见AST抽象语法树的影子,其中不乏有vue.re ...
- DVWA靶场实战(六)——Insecure CAPTCHA
DVWA靶场实战(六) 六.Insecure CAPTCHA: 1.漏洞原理: Insecure CAPTCHA(不安全的验证码),CAPTCHA全程为Completely Automated Pub ...
- [Python]Python调用Matlab (Pycharm版本)
目录 第一步:生成Build文件夹 第二步: 复制build文件夹到Pycharm下 第三步:调用代码 第一步:生成Build文件夹 C:\Program Files\MATLAB\R2016a\ex ...
- GIS数据下载合集:遥感、土壤、气象、行政区数据...
本文介绍GIS领域相关的各类综合数据免费获取网站,包括遥感数据.气象数据.土地数据.土壤数据.农业数据.行政区数据.社会数据.经济数据等等. 数据较多,大家可以直接通过下方目录加以总览:点击数 ...
- ZXing CaptureActivity黑屏问题
关于zxing captureActivity黑屏的问题,我在网上搜索一下,结果发现几乎没有这方面的资料.后来自己用了半天时间,独步跟踪调试,查看相机类的代码,最后发现了一点问题,就是关闭相机的时候没 ...