Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式
Jlion 人气:0
## 一、前言
上一篇我分享了一篇关于 [Asp.Net Core 中IdentityServer4 授权中心之应用实战](https://www.cnblogs.com/jlion/p/12447081.html) 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完美,之后我经过自己的学习查阅并阅读了相关源代码,发现 `IdentityServer4` 可以实现自定义`GrantType` 授权方式。
*声明*:看这篇文章时如果你没有阅读我上一篇 [Asp.Net Core 中IdentityServer4 授权中心之应用实战](https://www.cnblogs.com/jlion/p/12447081.html) 的文章,那请先移步看上面的文章,再来看这篇文章会更加清晰,感谢支持,感谢关注!
## 二、场景模拟
上篇文章已经把电商系统从单一网关架构升级到多网关架构,架构图如下:
![](https://img2020.cnblogs.com/blog/824291/202003/824291-20200310111100212-1434441217.png)
然而上面的`授权中心` 使用的是`密码授权模式`,但是对于`微信小程序`、`微信公众号商城`端使用的授权还不是很合适;
`微信小程序`和`微信公众号`微商城客户端的场景如下:
用户访问小程序商城或者微信公众号商城后会到`微信服务端`获得授权拿到相关的用户`openId`、`unionId`、`userName` 等相关信息,再携带`openId`、`unionId`、`userName`等信息访问`授权中心`网关,进行授权,如果不存在则自动注册用户,如果存在则登录授权成功等操作。那这个场景后我该如何改造`授权中心`服务网关呢?经过研究和探讨,我把上面的架构图细化成如下的网关架构图:
![](https://img2020.cnblogs.com/blog/824291/202003/824291-20200312110224389-2025910734.png)
## 三、授权中心改造升级
上一篇文章中我们的解决方案中已经建立了三个项目:
- `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
///
/// 验证用户
///
///
///
///
private async Task
- > ValidateUserAsync(string openId, string unionId)
{
//TODO 这里可以通过openId 和unionId 来查询用户信息(数据库查询),
//我这里为了方便测试还是直接写测试的openId 相关信息用户
var user = OAuthMemoryData.GetWeiXinOpenIdTestUsers();
if (user == null)
{
//注册用户
}
return new List
加载全部内容