查阅了大多数相关资料,总结设计一个IdentityServer4认证授权方案,我们先看理论,后设计方案。
1、快速理解认证授权
我们先看一下网站发起QQ认证授权,授权通过后获取用户头像,昵称的流程。
1、输入账号密码,QQ确认输入了正确的账号密码可以登录 --->认证
2、下面需要勾选的复选框(获取昵称、头像、性别)----->授权
点击授权并登录后,登录后就可以凭借QQ授权的授权码去获取昵称、头像、性别了。
是不是看起来流程很简单?对,就是这么简单,换成我们自己的网站也是一样的。
比如公司开发出很多业务网站,网站1、网站2、网站3......,然后我们想使用同一个账号登录后,其他网站打开也是登录状态。
这个时候只需要有一个统一认证登录平台(类似于QQ认证授权),然后就可以实现了,避免了一个网站一个账号,每次都需要输入账号密码的情况了。
2、IdentityServer4的概念?
IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现。
看下面这张图理解一下这个概念,看不懂?没关系,不影响你敲代码的速度,接着往下看。
对上图各个节点的解释:
IdentityServer
身份认证服务器是一个实现了OpenID Connect和OAuth 2.0协议的身份提供者,它负责向客户端发布安全令牌
User
使用注册客户端访问资源的用户
Client
客户端从标识服务器请求令牌,要么用于认证用户(请求身份令牌),要么用于访问资源(请求访问令牌)
客户端必须首先在身份服务器上注册,然后才能请求令牌
这里的客户端可以是web应用程序、native mobile, desktop applications, SPA 等程序
Resource
资源是你想要用身份认证服务器保护的东西,如:用户的身份数据或api
每个资源都有一个惟一的名称,客户端使用这个名称来指定他们想要访问的资源
关于用户的身份数据标识(也称为claim),例如姓名或电子邮件地址
Identity Token
身份令牌代表身份验证过程的结果
Access Token
访问令牌授权客户端以允许访问哪些API资源,访问令牌包含客户端和用户的信息
2.1、OpenID Connect(认证)
OpenID Connect由OpenID基金会于2014年发布的一个开放标准, 是建立在OAuth 2.0协议上的一个简单的身份标识层, OpenID Connect 兼容 OAuth 2.0. 实现身份认证(Authentication)
参考资料:https://openid.net/connect/
OpenID Connect文档:https://openid.net/specs/openid-connect-discovery-1_0.html
这里用JSON Web Token(JWT:RFC7519),它包含一组关于用户身份的声明(claim),如:用户的标识(sub)、颁发令牌的提供程序的标识符(iss)、创建此标识的Client标识(aud),还包含token的有效期以及其他相关的上下文信息。
2.2、OAuth2.0(授权)
OAuth2.0是一个开放的工业标准的授权协议(Authorization),它允许用户授权让第三方应用直接访问用户在某一个服务中的特定资源,但不提供给第三方账号及密码信息。
参考资料:https://www.cnblogs.com/xiandnc/p/9763121.html
OAuth2.0 文档:https://tools.ietf.org/html/rfc6749#page-73
OAuth2.0四种授权方式:http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
认证是身份识别,鉴别你是谁;
授权是授权许可,告诉你可以做什么。
如上图的网站发起QQ认证授权,登录QQ是认证身份,鉴别你是谁,勾选复选框授权是授权许可,告诉你可以做什么(读取头像,昵称、性别)。
具体概念就不展开了,大家点击上面的参考资料可以了解详细内容,OAuth整体流程如下:
客户端必须得到用户的授权,才能获取令牌。
OAuth2.0定义了四种授权方式(除了这是四种,可以自定义授权模式,如:短信模式、邮箱模式等):
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
2.3、IdentityServer4功能特性
用户认证服务
基于OpenID Connect实现的独立的认证服务实现对多平台(web, native, mobile, services)的集中认证
API访问授权
为各种类型的客户机颁发api访问令牌,例如服务器到服务器、web应用程序、spa和native/mobile程序
联合身份认证
支持外部身份提供者,如Azure Active Directory、Google、Facebook等
定制化的实现
IdentityServer4的许多方面可以定制以满足您的需要,因为它是一个框架,而不是SaaS服务,所以可以通过编写代码来调整实现,以适应不同的场景
成熟的开原方案
使用许可的Apache2开源协议,允许在其之上构建商业产品,也作为.NET基金会支持的项目 (https://dotnetfoundation.org/projects?type=project&ps=10&pn=6)
提供免费的商业支持
官方可以对使用者提供部分的免费商业支持
3、场景演示:认证授权系统架构设计方案
电商场景设计方案(初稿)
系统架构图如下:
这张架构图缺点:
- 发布频繁,发布影响整个系统;
- 很难做到敏捷开发;
- 维护性可能会存在一定的弊端,主要看内部架构情况;
大多数对于多客户端登录授权来说可能已经实现了Oauth 2.0 的身份授权验证,但是是和业务集成在一个网关里面,这样不是很好的方式;
我们可以把里面的很多业务单独建立一个独立的网关(比如代理商业务,或者其他比较频繁操作的业务以及第三方业务),并且把授权服务一并独立出来,调整后的系统架构图如下:
身份授权从业务系统中独立出来后,有了如下的优势:
- 授权服务不受业务的影响,如果业务网关宕机了,那至少不会影响代理商网关的业务授权系统的使用;
- 授权服务一旦建立,一般就很难进行升级,除非特殊情况;
- 在敏捷开发中,业务系统可能发布频繁(升级更新),这样也不至于影响了授权系统服务导致代理商业务受到影响;
代理商业务独立后,代理商可能会增加秒杀活动,秒杀时支付订单集中在某一时刻翻了十几倍,这时候整个API网关可能扛不住,
如果数据过多,增加几台负载服务器可能也有点吃力,以至于整个业务系统受到影响;
这个时候把支付业务从系统中拆分出成独立的支付网关,并做了一定的负载,这时候系统架构图就演变成如下:
支付业务独立后的优势:
- 支付网关服务更新不会太频繁,减少整个系统因为发布导致的一系列问题,增强稳定性;
- 支付系统出现宕机不影响整个系统的使用,用户还可以使用其他操作,技术和运维人员也比较好排查定位问题所在;
授权中心单独一个网关,访问API网关、支付业务网关
、代理商业务网关
都需要先通过授权中心
获得授权拿到访问令牌AccessToken
才能正常的访问这些网关,
这样授权模块就不会受任何的业务影响,同时各个业务网关也不需要写同样的授权业务的代码;
业务网关
仅仅只需关注本身的业务即可,授权中心
仅仅只需要关注维护授权;
经过这样升级改造后整个系统维护性得到很大的提高,相关的业务也可以针对具体情况进行选择性的扩容。
参考文献
Asp.Net Core IdentityServer4 中的基本概念:https://www.cnblogs.com/jlion/p/12437441.html
IdentityServer4+Vue+asp.netcore开源项目地址:https://www.cnblogs.com/WQLBlog/p/12356853.html
Asp.Net Core 中IdentityServer4 授权中心之应用实战:https://www.cnblogs.com/jlion/p/12447081.html
基于IdentityServer4 实现.NET Core的认证授权:https://www.cnblogs.com/xiandnc/p/10150814.html