Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式

一、前言

上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完美,之后我经过自己的学习查阅并阅读了相关源代码,发现 IdentityServer4 可以实现自定义GrantType 授权方式。

声明:看这篇文章时如果你没有阅读我上一篇 Asp.Net Core 中IdentityServer4 授权中心之应用实战的文章,那请先点击下面的链接移步阅读,再来看这篇文章会更加清晰,感谢支持,感谢关注!

  • Asp.Net Core 中IdentityServer4 授权中心之应用实战

二、场景模拟

上篇文章已经把电商系统从单一网关架构升级到多网关架构,架构图如下:

然而上面的授权中心 使用的是密码授权模式,但是对于微信小程序微信公众号商城端使用的授权还不是很合适; 微信小程序微信公众号微商城客户端的场景如下:用户访问小程序商城或者微信公众号商城后会到微信服务端获得授权拿到相关的用户openIdunionIduserName 等相关信息,再携带openIdunionIduserName等信息访问授权中心网关,进行授权,如果不存在则自动注册用户,如果存在则登录授权成功等操作。那这个场景后我该如何改造授权中心服务网关呢?经过研究和探讨,我把上面的架构图细化成如下的网关架构图:

三、授权中心改造升级

通过上面的需求场景分析,我们目前的授权中心还不满足这种需求,故我们可以通过IdentityServer4 自定义授权方式进行改造升级来满足上面的场景需求。

经过查看源代码我发现我们可以通过实现IExtensionGrantValidator抽象接口进行自定义授权方式来实现,并且实现ValidateAsync 方法, 现在我在之前的解决方案授权中心项目中新增WeiXinOpenGrantValidator类代码如下:

public class WeiXinOpenGrantValidator : IExtensionGrantValidator
{public string GrantType => GrantTypeConstants.ResourceWeixinOpen;public async Task ValidateAsync(ExtensionGrantValidationContext context){try{#region 参数获取var openId = context.Request.Raw[ParamConstants.OpenId];var unionId = context.Request.Raw[ParamConstants.UnionId];var userName = context.Request.Raw[ParamConstants.UserName];#endregion#region 通过openId和unionId 参数来进行数据库的相关验证var claimList = await ValidateUserAsync(openId, unionId);#endregion#region 授权通过//授权通过返回context.Result = new GrantValidationResult(subject: openId,authenticationMethod: "custom",claims: claimList.ToArray());#endregion}catch (Exception ex){context.Result = new GrantValidationResult(){IsError = true,Error = ex.Message};}}#region Private Method/// <summary>/// 验证用户/// </summary>/// <param name="loginName"></param>/// <param name="password"></param>/// <returns></returns>private async Task<List<Claim>> ValidateUserAsync(string openId, string unionId){//TODO 这里可以通过openId 和unionId 来查询用户信息(数据库查询),//我这里为了方便测试还是直接写测试的openId 相关信息用户var user = OAuthMemoryData.GetWeiXinOpenIdTestUsers();if (user == null){//注册用户}return new List<Claim>(){new Claim(ClaimTypes.Name, $"{openId}"),};}#endregion}

GrantTypeConstants 代码是静态类,主要用于定义GrantType的自定义授权类型,可能后续还有更多的自定义授权方式所以,统一放这里面进行管理,方便维护,代码如下:

 public static class GrantTypeConstants{/// <summary>/// GrantType - 微信端授权/// </summary>public const string ResourceWeixinOpen = "weixinopen";}

ParamConstants 类主要是定义自定义授权需要的参数,代码如下:

public class ParamConstants
{public const string OpenId = "openid";public const string UnionId = "unionid";public const string UserName = "user_name";
}

好了上面的自定义验证器已经实现了,但是还不够,我们还需要让客户端支持自定义的授权类型,我们打开OAuthMemoryData代码中的GetClients,代码如下:

public static IEnumerable<Client> GetClients()
{return new List<Client>{new Client(){ClientId =OAuthConfig.UserApi.ClientId,AllowedGrantTypes = new List<string>(){GrantTypes.ResourceOwnerPassword.FirstOrDefault(),//Resource Owner Password模式GrantTypeConstants.ResourceWeixinOpen,//新增的自定义微信客户端的授权模式},ClientSecrets = {new Secret(OAuthConfig.UserApi.Secret.Sha256()) },AllowedScopes= {OAuthConfig.UserApi.ApiName},AccessTokenLifetime = OAuthConfig.ExpireIn,},};
}

客户端AllowedGrantTypes 配置新增了我刚刚自定义的授权方式GrantTypeConstants.ResourceWeixinOpen, 现在客户端的支持也已经配置好了,最后我们需要通过AddExtensionGrantValidator<>扩展方法把自定义授权验证器注册到DI中,代码如下:

public void ConfigureServices(IServiceCollection services)
{services.AddControllers();#region 数据库存储方式services.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryApiResources(OAuthMemoryData.GetApiResources())//.AddInMemoryClients(OAuthMemoryData.GetClients()).AddClientStore<ClientStore>().AddResourceOwnerValidator<ResourceOwnerPasswordValidator>().AddExtensionGrantValidator<WeiXinOpenGrantValidator>();#endregion}

好了,简单的授权中心代码升级已经完成,我们分别通过命令行运行授权中心用户业务网关 ,之前的用户业务网关无需改动任何代码,运行图分别如下:

Jlion.NetCore.Identity.Server 授权中心运行如下:

Jlion.NetCore.Identity.UserApiServer 用户业务网关运行如下

我们现在用postman模拟openIdunionIduserName参数来请求授权中心获得AccessToken,请求如下:

我们再通过postman 携带授权信息访问用户业务网关数据,结果图如下:

好了,自定义授权模式已经完成,简单的授权中心也已经升级完成,上面WeiXinOpenGrantValidator验证器中我没有直接走数据库方式进行验证和注册,简单的写了个Demo ,大家有兴趣可以 把TODO那一块数据库的操作去实现,代码我已经提交到 github上了,这里再次分享下我博客同步实战的demo 地址 https://github.com/a312586670/IdentityServerDemo

四、思考与总结

本篇我介绍了自定义授权方式,通过查看源代码及查阅资料学习了IdentityServer4 可以通过自定义授权方式进行扩展。这样授权中心可以扩展多套授权方式,比如今天所分享的 自定义微信openId 授权、短信验证码授权等其他自定义授权,一套Api资源可以兼并多套授权模式,灵活扩展,灵活升级。本篇涉及的知识点不多,但是非常重要,因为我们在使用授权中心统一身份认证时经常会遇到多种认证方式的结合,和多套不同应用用户的使用,在掌握了授权原理后,就能在不同的授权方式中切换的游刃有余,到这里有的博友会问AccentToken 有过期时间,会过期怎么办?难道要重新授权一次吗?这些问题我会安排下一篇文章分享。

灵魂一问:

上面的授权中心 例子主要是为了让大家更好的理解自定义授权的使用场景及它的灵活性,真实的场景这样直接把 openId等相关信息来验证授权安全吗?大家可以思考下,如果不安全大家又有什么好的解决方案呢?自我提升在于不停的自我思考,大家可以敬请的发挥自己的思考,把解决方案留在留言板中,以供大家参考学习,感谢!!!

如果觉得对你有用,希望帮忙点下右下角星星,写文章、写代码都不容易。鼓励下坚持写文章的动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

缺失值处理

处理思路 在数据预处理过程中&#xff0c;难免会有数据的确实情况&#xff0c;无论是自己爬虫获取的还是从公开数据源上获取的数据集&#xff0c;都不能保证数据集是完全准确的&#xff0c;难免会有一些缺失值。而以这样数据集为基础进行建模或者数据分析时&#xff0c;缺失值…

2019年第十届蓝桥杯国赛B组试题B-质数拆分-01背包问题+素数筛选

问题描述】 2019可以被分解成若干个两两不同的素数&#xff0c;请问不同的分解方案有多少种&#xff1f; 注意&#xff1a;分解方案不考虑顺序&#xff0c;如 2 2017 2019 和 2017 2 2019 属于同一种方案。答案&#xff1a;55965365465060 代码如下&#xff1a; #includ…

在线教育,异军突起,有一种华丽转身,叫做.NET在线讲师!(全职/兼职皆可)...

在线教育2020年&#xff0c;注定是不平凡的一年&#xff0c;疫情来袭&#xff0c;人们只能潜伏在家&#xff0c;很多人因此没有了收入甚至没有了工作&#xff0c;各个行业&#xff0c;也正在快速升级和重新洗牌&#xff0c;这其中&#xff0c;有一个行业&#xff0c;异军突起&a…

python计算相关系数

皮尔逊相关系数 用numpy实现 import numpy as npx np.array([1, 4, 3, 5]) y np.array([1, 3, 4, 5]) pc np.corrcoef(x, y)print(pc)输出结果&#xff1a; 调用scipy.stats中的pearsonr方法 from scipy.stats import pearsonr import numpy as npx np.array([1, 4, 3,…

2018年第九届蓝桥杯国赛B组试题B-激光样式-dfs

【问题描述】 x星球的盛大节日为增加气氛&#xff0c;用30台机光器一字排开&#xff0c;向太空中打出光柱。 安装调试的时候才发现&#xff0c;不知什么原因&#xff0c;相邻的两台激光器不能同时打开&#xff01; 国王很想知道&#xff0c;在目前这种bug存在的情况下&#xf…

领域模型

领域模型是对领域内的概念类或现实世界中对象的可视化表示。又称概念模型、领域对象模型、分析对象模型。它专注于分析问题领域本身&#xff0c;发掘重要的业务领域概念&#xff0c;并建立业务领域概念之间的关系。学会了面向对象的思想&#xff0c;却依然写不出好的面向对象的…

含根号的导数怎么求_数学分析Mathematical Analysis笔记整理 第四章 导数与微分

第四章 导数与微分导数的概念一、引例1. 瞬时速度&#xff08;变速直线运动&#xff09;2. 切线的斜率二、导数的定义&#xff08;1&#xff09;导数定义1&#xff1a;若 在 点某邻域上有定义&#xff0c;且 存在&#xff0c;则称 在 点可导&#xff0c;该极限值称为 在 点的导…

重新定义代理的扩展性:WebAssembly在Envoy与Istio中的应用

原文&#xff1a;https://istio.io/blog/2020/wasm-announce/作者&#xff1a;CRAIG BOX, MANDAR JOG, JOHN PLEVYAK, LOUIS RYAN, PIOTR SIKORA (GOOGLE), YUVAL KOHAVI, SCOTT WEISS (SOLO.IO)译者&#xff1a;陆培尔编者按Istio的架构在1.5版本中发生了翻天覆地的变化&#…

srs10流程图_高效的SRS资源指示方法与流程

公开的主题一般涉及电信&#xff0c;更特别地涉及下一代移动无线通信系统中的srs资源的高效指示。背景技术&#xff1a;下一代移动无线通信系统(5g或nr)将支持各种用例集合和各种部署场景集合。后者包括在低频(数百mhz)(与如今的lte类似)和甚高频(数十ghz的毫米波)两者处的部署…

2019年第十届蓝桥杯国赛B组试题E-路径计数-dfs(坑题)

【问题描述】 从一个 5 x 5 的方格矩阵的左上角出发&#xff0c;沿着方格的边走&#xff0c;满足以下条件的路线有多少种&#xff1f; 总长度不超过 12&#xff1b; 最后回到左上角&#xff1b; 路线不自交&#xff1b; 不走出 5 x 5 的方格矩阵范围之外。如下图所示&#xff…

python中开关_pyq中的开关按钮

可以用pyqt5创建一个开关按钮吗&#xff1f;在我正在用pyqt5在python中设计一个过滤工具。用户甚至可以对其数据进行过滤或合并。在我在qtablewidget中显示可能的过滤器&#xff0c;用户可以使用复选框选择要应用的过滤器。在每一行中&#xff0c;复选框都是独占的&#xff0c;…

2019年第十届蓝桥杯国赛B组试题G-排列数-next_permutation枚举,模拟

在一个排列中&#xff0c;一个折点是指排列中的一个元素&#xff0c;它同时小于两边的元素&#xff0c;或者同时大于两边的元素。 对于一个 1∼n 的排列&#xff0c;如果可以将这个排列中包含 t个折点&#xff0c;则它称为一个 t1 单调序列。 例如&#xff0c;排列 (1,4,2,3)…

.NET Core开发实战(第22课:异常处理中间件:区分真异常与逻辑异常)--学习笔记(下)...

接下来介绍使用代理方法的方式&#xff0c;也就是说把 ErrorController 整段逻辑直接定义在注册的地方&#xff0c;使用一个匿名委托来处理&#xff0c;这里的逻辑与之前的逻辑是相同的app.UseExceptionHandler(errApp > {errApp.Run(async context >{// 在 Features 里面…

2019年第十届蓝桥杯国赛B组试题A-平方序列-枚举

【问题描述】 小明想找到两个正整数 X 和 Y&#xff0c;满足 2019 < X < Y;2019^2 , X^2 , Y^2 组成等差数列。请你求出在所有可能的解中&#xff0c;X Y 的最小值是多少&#xff1f; 答案提交 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。 本题的结…

lcd刷新慢_LCD1602刷新率很慢的问题

#include"lcd.h"/******************************************************************************** 函 数 名 : Lcd1602_Delay1ms* 函数功能 : 延时函数&#xff0c;延时1ms********************************************************…

【朝夕技术专刊】Core3.1WebApi_Filter-Authorize详解

欢迎大家阅读《朝夕Net社区技术专刊》第6期我们致力于.NetCore的推广和落地&#xff0c;为更好的帮助大家学习&#xff0c;方便分享干货&#xff0c;特创此刊&#xff01;很高兴你能成为忠实读者&#xff0c;文末福利不要错过哦&#xff01;前言&#xff1a;本部分文档将详细给…

2019年第十届蓝桥杯国赛B组试题D-求值-枚举

【问题描述】 学习了约数后&#xff0c;小明对于约数很好奇&#xff0c;他发现&#xff0c;给定一个正整数 t&#xff0c;总是可以找到含有 t 个约数的整数。 小明对于含有 t 个约数的最小数非常感兴趣&#xff0c;并把它定义为 St 。 例如 S1 1, S2 2, S3 4, S4 6&#…

pythonimport是拷贝_02Python学习笔记之二.一【import、==和is、深浅拷贝】2019-08-17

章节号内容1图片格式(png)宽度大于620px,保持高宽第1章节  import模块1-1 import模块—sys.path↓import导入模块的搜索路径&#xff1a;In [1]: import sysIn [2]: sys.pathOut[2]:#第一个为当前路径[,/usr/lib/python36.zip,/usr/lib/python3.6,/usr/lib/python3.6/lib-dyn…

以正确的方式下载和配置 ASP.NET Core 官方源码

我们可以在Github上面直接查看ASP.NETCore 3.x的源代码&#xff0c;但是我们也可以把源代码下载下来进行查看。而下载源代码进行查看有很多好处&#xff1a;任意的导航源代码内置了一个示例项目直接调试源代码下载源代码想下载并配置好源码&#xff0c;你需要&#xff1a;最新版…

2017年第八届蓝桥杯国赛B组试题A-36进制-进制转换

【问题描述】 对于16进制&#xff0c;我们使用字母A-F来表示10及以上的数字。 如法炮制&#xff0c;一直用到字母Z&#xff0c;就可以表示36进制。 36进制中&#xff0c;A表示10&#xff0c;Z表示35&#xff0c;AA表示370 你能算出 MANY 表示的数字用10进制表示是多少吗?【答…