.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

介绍JwtToken认证之前,必须要掌握.Net Core认证系统的核心原理,如果你还不了解,请参考.Net Core 认证组件源码解析,且必须对jwt有基本的了解,如果不知道,请百度.最重要的是你还需要掌握identity server4的基本用法,关于identity server4因为设计到两个协议Oath2.0和openid connect协议,内容较多,不是本文重点,后续有时间我会写一片关于identity server4的源码分析.且为了保证整个系统的高度可控,我重写了整个id4,留下了password模式.如果有兴趣,可以关注本人的后续文章.

假设你已经掌握以上内容,那么整个流程可以抽象为如下步骤:

(1)、用户输入用户名密码同时带着客户端Id和客户端密钥去identity server4请求access token.(访问令牌,令牌中带着用户Id,带着客户端的名称和密码)

(2)、拿到token后,接着用户去请求客户端指定的控制器方法,那么客户端第一步,会解析token中的客户端名称和密码是否正确,还有过期时间等常规字段的判断.

(3)、token验证通过,这个时候就可以拿到用户信息(ClaimsPrincipal)

(4)、此时我们拿到持有的用户信息中的用户Id,发起httpclient或者grpc调用,去统一权限系统查找用户的权限是否有当前请求的方法,有就通过授权认证,返回数据,没有,就返回权限不足.

整个流程大致如上,本文的重点是当拿到id4颁发的有效令牌(token)后,客户端如何解析?

微软提供了IdentityServer4.AccessTokenValidation类库,用来解析id4颁发的token.

.Net Core启用IdentityServer4token验证的方法如下:

 .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

指定id4的认证方案,并指定认证参数,那么看看里面到底干了什么

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 因为id4的令牌有访问令牌和引用令牌之分,但是password模式,只支持访问令牌,所以

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 这两块这里就不分析了,如果你的项目用到了引用令牌.那么自行查阅代码.

ok,回到第一行代码

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 很明显添加了JwtBearer的认证方案.所以IdentityServer4.AccessTokenValidation类库是基于

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

回到.Net Core JwtBear认证的源码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 很简单,添加了方案名称为Bearer IdentityServerAuthenticationJwt的认证方案,且处理器为JwtBearerHandler,并指定参数.如果你已经掌握.Net Core的核心认证组件的流程,那么啥都不用说,直接看JwtBearerHandler干了什么,查看核心的认证方法HandleAuthenticateAsync,源码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 第一步,生成上下文,执行通过JwtBearerOptions参数注册的MessageReceived事件,源码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 所以,在token认证前,可以随意操作上下文,微软提示,给当前应用一个机会去拒绝一部分token。当然很明显,你可以干除了拒绝之外的很多事情.

接着

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 检查http head头中的token是否合法,条件代码中也给出了.必须以Bearer开头等

接下来,这段代码就很有趣了,如果你不了解identity Server4,你肯定无法下手.

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 核心对象

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 这个对象在IdentityModel类库中有,但是这里不介绍了

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

协议层面的东东,所以可以自行查询源码.

接着回到JwtBearer认证的入口

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 为啥要注入JwtBearerPostConfigureOptions这个配置对象呢?且这个配置对象是干嘛的呢?关于PostConfigureOpetions是.Net Core核心配置系统里面的一类对象,这类对象会在Options执行完毕之后执行,类似ABP模块加载系统的生命周期管理,执行完Init之后执行Post里面的方法,这里本质也是如此.ok,看看这个配置干了什么,源码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 到这里一目了然.ConfigurationManager实际就是去远程调用文档配置(本质是去拿给token前面的rsa文件,来给token解密,并验证token的有效性)用的.

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 调用的是id4的文档配置,但是我为了减少不必要的远程调用,拿掉了id4的文档发现TokenPoint.改用在客户端直接配置ras文件,来给token解密,这里因为我用的是password模式,所有的系统都是高度信任的.所以可以这样做.而且微软也考虑到了这一点,代码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 你可以跳过远程调用,而改用本地直接配置.参数在JwtBearerOptions的TokenValidationParameters属性中配置.

这个时候你已经通过本地配置,或者通过调用id4的文档发现TokenPoint拿到了给token签名的rsa文件,接着

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 调用JwtBearerOptions配置参数中的SecurityTokenValidators,源码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 本质就是调用JwtSecurityTokenHandler去验证token的内容是否有效,并解析出用户信息,源码如下:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 并返回认证结果.

所以整个核心认证流程如下:

1、拿到http请求上下文中的token

2、执行一系列事件

3、远程调用id4文档发现服务拿到签名rsa文件或者本地指定rsa文件

4、用私钥解密token,判断其有效性

5、执行一系列事件

6、返回用户认证结果

整个核心的流程可以抽象出如下代码:

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

 此时就拿到可以访问的token,里面包含用户Id的信息,接着配合授权系统的动态授权功能,去权限系统判断当前用户是否具有访问当前Api的权限.就能判断当前请求是否被允许

这里只介绍了id4 token的核心认证流程,一些细节点,比如token的有效性校验,就有很多内容没介绍.不明白,可以在下面提问.

注意:如果你和我一样重写了id4,同时你拿掉了文档发现tokenPoint,那么就不能用IdentityServer4.AccessTokenValidation组件了(我暂时没找到,我觉得也没必要,直接自己写了),只能使用JwtBear认证组件,再参考

IdentityServer4.AccessTokenValidation组件中的IdentityServerAuthenticationOptions参数中的ConfigureJwtBearer方法指定JwtBear必须的认证参数,来实现自定以的Id4token验证.

.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

纯属个人理解,能力有限,有问题,请指正,谢谢