一、前言

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

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

二、场景模拟

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

然而上面的授权中心 使用的是密码授权模式,但是对于微信小程序微信公众号商城端使用的授权还不是很合适;

微信小程序微信公众号微商城客户端的场景如下:

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

三、授权中心改造升级

上一篇文章中我们的解决方案中已经建立了三个项目:

  • Jlion.NetCore.Identity.Service授权中心 网关 - WebApi 项目
  • Jlion.NetCore.Identity.UserApiService用户业务网关 -WebApi项目
  • Jlion.NetCore.Identity基础类库,主要用于把公共的基础设施层放到这一块

通过上面的需求场景分析,我们目前的授权中心还不够这种需求,故我们可以通过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等相关信息来验证授权安全吗?大家可以可以思考下,如果不安全大家又有什么好的解决方案呢?自我提升在于不停的自我思考,大家可以敬请的发挥自己的思考,把答案留在留言板中,以供大家参考学习,感谢!!!

Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式的更多相关文章

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

    一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...

  2. Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用

    一.前言 上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权 ...

  3. Asp.Net Core 中IdentityServer4 实战之角色授权详解

    一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...

  4. Asp.Net Core 中IdentityServer4 实战之 Claim详解

    一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会 ...

  5. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  6. asp.net Core 中AuthorizationHandler 实现自定义授权

    前言 ASP.NET Core 中 继承的是AuthorizationHandler ,而ASP.NET Framework 中继承的是AuthorizeAttribute. 它们都是用过重写里面的方 ...

  7. ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作

    前言:马上要过年了,祝大家新年快乐!在过年回家前分享一篇关于Zookeeper的文章,我们都知道现在微服务盛行,大数据.分布式系统中经常会使用到Zookeeper,它是微服务.分布式系统中必不可少的分 ...

  8. 第十五节:Asp.Net Core中的各种过滤器(授权、资源、操作、结果、异常)

    一. 简介 1. 说明 提到过滤器,通常是指请求处理管道中特定阶段之前或之后的代码,可以处理:授权.响应缓存(对请求管道进行短路,以便返回缓存的响应). 防盗链.本地化国际化等,过滤器用于横向处理业务 ...

  9. ASP.NET Core 中jwt授权认证的流程原理

    目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...

随机推荐

  1. phpcms添加图片投票

    1phpcms加入投票选项的图片上传功能,从我的文件下载,然后到phpcms目录下直接覆盖即可. 当然这边出现了一个bug,修改投票选项不能修改的bug,只需要修改vote_option_class. ...

  2. 因为AI,所以爱

    作为技术驱动型公司 自我颠覆的核心就是技术上有所突破 2019技术奇点大会上,创始人行在提出 「未来,大数据和人工智能 将成为商业升级的智能发动机」 这与我们的使命不谋而合 时间退回到2016年的冬天 ...

  3. 吴裕雄--天生自然python学习笔记:python用 Selenium 组件实现浏览器操作自动化

    一般情况下,我们都是用手工操作的方式来对浏览器进行各种操作 . 实际上, 只要我们安装一个自动化操作组件, Python 就可以让我们的很多操作实现自动化 . Selenium 组件 在开发网页时,用 ...

  4. 用Microsoft Chart Controls(MSChart)实现曲线图,并支持拖动放大到秒

    Microsoft Chart Controls(简称MSChart)控件,给图形统计和报表图形显示提供了很好的解决办法,同时支持Web和WinForm两种方式. MSChart 在.NET 4.0自 ...

  5. continuing|offensive

    the fact of something continuing for a long period of timewithout being changed or stopped 连续性,持续性,连 ...

  6. Java过滤器Filter的原理及配置_学习笔记

    Filter中文意思为过滤器.顾名思义,过滤器可在浏览器以及目标资源之间起到一个过滤的作用.例如:水净化器,可以看成是生活中的一个过滤器,他可以将污水中的杂质过滤,从而使进入的污水变成净水. 对于WE ...

  7. SSM 生成mapper中xml文件:未能解析映射资源:“文件嵌套异常

    错误日记我就网上随便找个贴着: 错误一: org.springframework.beans.factory.BeanCreationException: Error creating bean wi ...

  8. GitHub下载

  9. js弱类型转换的知识点

    本文属于转载知识点,以下是原博文作者:不死鸟哇的文章,文章链接:原文JavaScript里什么情况下a==!a为true呢? 今天群里有位同学问了这样一个问题,JavaScript在什么情况下会出现变 ...

  10. AI能帮我们造出一个无肉的世界吗?

    AI听起来很遥远,其实已经渗透到我们的日常工作和生活中.在不远的未来,互联网.大数据.硬件的发展和软件的优化,乃至全社会的参与,人工智能将真正从实验室走进生活,它将成为改变我们生活的一部分.我们吃的肉 ...