赞
踩
统一鉴权认证是一个基础服务。它几乎在所有企业内部都需要,企业内部只要有两个以上系统存在,就有必要实现一套统一的授权系统,否则用户使用非常地麻烦,需要在不同系统之间来回登录切换。特别是在微服务大行其道的今天,这个统一授权认证服务更是一个基础和关键入口。实现的方案有很多种,但都大同小异。
本文主要介绍授权认证服务架构方案设计及实现,这个实践也是本人在企业内部成功实现的经验总结。从旧有系统Cas认证方式到升级Oauth2.0认证,怎么保持两套认证体(Cas和Oauth2)互认整个过程遇到不少问题,以及针对问题解决。将从如下几个方面进行描述。文章比较长,各位看官花点耐心呀!
目录结构
1、概念介绍
1.1、什么是认证
1.2、什么是授权
1.3、什么是鉴权
1.4、什么是权限控制
1.5、三者关系
2、Http认证方案
2.1 认证流程图
2.2 认证步骤解析
2.3 优缺点对比
2.4 使用场景
3、Session-Cookie认证方案
3.1 认证流程图
3.2 认证步骤解析
3.3 优缺点对比
3.4 使用场景
3.5 代码实现
4、Token认证方案
4.1 Token认证原理
4.2 刷新Token
4.3 Token与Session-Cookie区别
5、OAuth2认证方案
5.1 OAuth2定义
5.2 OAuth2角色
5.3 OAuth2认证流程
6、JWT认证方案
6.1 JWT定义
6.2 JWT组成
6.3 JWT使用
6.4 JWT认证流程
6.5 JWT优缺点
7、集团统一授权认证架构方案
5.1 方案设计
5.2 关键问题
5.3 企业内部实践
5.4 关键代码
8、总结
1、概念介绍
1.1、什么是认证
认证(Identification)是指根据声明者所特有的识别信息,确认声明者的身份。
白话文的意思就是:你需要用身份证证明你自己是你自己。
比如我们常见的认证技术:
1.2、什么是授权
授权(Authorization):在信息安全领域是指资源所有者委派执行者,赋予执行者指定范围的资源操作权限,以便对资源的相关操作。
在现实生活领域例如:银行卡(由银行派发)、门禁卡(由物业管理处派发)、钥匙(由房东派发),这些都是现实生活中授权的实现方式。
在互联网领域例如:web 服务器的 session 机制、web 浏览器的 cookie 机制、颁发授权令牌(token)等都是一个授权的机制。
1.3、什么是鉴权
鉴权(Authentication)在信息安全领域是指对于一个声明者所声明的身份权利,对其所声明的真实性进行鉴别确认的过程。
若从授权出发,则会更加容易理解鉴权。授权和鉴权是两个上下游相匹配的关系,先授权,后鉴权。
在现实生活领域:门禁卡需要通过门禁卡识别器,银行卡需要通过银行卡识别器;
在互联网领域:校验 session/cookie/token 的合法性和有效性
鉴权是一个承上启下的一个环节,上游它接受授权的输出,校验其真实性后,然后获取权限(permission),这个将会为下一步的权限控制做好准备。
1.4、什么是权限控制
权限控制(Access/Permission Control)将可执行的操作定义为权限列表,然后判断操作是否允许/禁止
对于权限控制,可以分为两部分进行理解:一个是权限,另一个是控制。权限是抽象的逻辑概念,而控制是具体的实现方式。
在现实生活领域中:以门禁卡的权限实现为例,一个门禁卡,拥有开公司所有的门的权限;一个门禁卡,拥有管理员角色的权限,因而可以开公司所有的门。
在互联网领域:通过 web 后端服务,来控制接口访问,允许或拒绝访问请求。
1.5 认证、授权、鉴权和权限控制的关系
看到这里,我们应该明白了认证、授权、鉴权和权限控制这四个环节是一个前后依次发生、上下游的关系,如下图所示:
需要说明的是,这四个环节在有些时候会同时发生。例如在下面的几个场景:
2、Http认证方案
在 HTTP 中,基本认证方案(Basic Access Authentication)是允许客户端(通常指的就是网页浏览器)在请求时,通过用户提供用户名和密码的方式,实现对用户身份的验证。
因为几乎所有的线上网站都不会走该认证方案,所以该方案大家了解即可
2.1 认证流程图
2.2 认证步骤解析
(1)客户端(如浏览器):向服务器请求一个受限的列表数据或资源,例如字段如下
GET /list/ HTTP/1.1
Host: www.baidu.com
Authorization: Basic aHR0cHdhdGNoOmY=
(2)服务器:客户端你好,这个资源在安全区 baidu.com里,是受限资源,需要基本认证;
并且向客户端返回 401 状态码(Unauthorized 未被授权的)以及附带提供了一个认证域www-Authenticate: Basic realm=”baidu.com”要求进行身份验证;
其中Basic就是验证的模式,而realm="baidu.com"说明客户端需要输入这个安全域的用户名和密码,而不是其他域的
HTTP/1.1 401 Unauthorized
www-Authenticate: Basic realm= "baidu.com"
(3)客户端:服务器,我已经携带了用户名和密码给你了,你看一下;(注:如客户端是浏览器,那么此时会自动弹出一个弹窗,让用户输入用户名和密码);
输入完用户名和密码后,则客户端将用户名及密码以 Base64 加密方式发送给服务器
传送的格式如下 (其中 Basic 内容为:用户名:密码 的 ase64 形式):
GET /list/ HTTP/1.1
Authorization: Basic Ksid2FuZzp3YW5n==
(4)服务器:客户端你好,我已经校验了Authorization字段你的用户名和密码,是正确的,这是你要的资源。
成功:HTTP/1.1 200 OK
失败:HTTP/1.1 403 Forbidden
2.3 优缺点对比
2.3.1 优点
实现简单,基本所有流行的浏览器都支持
2.3.2 缺点
(1)不安全:
(2)无法主动注销:
由于 HTTP 协议没有提供机制清除浏览器中的 Basic 认证信息,除非标签页或浏览器关闭、或用户清除历史记录。
2.4 使用场景
内部网络,或者对安全要求不是很高的网络。
3、Session-Cookie认证方案
Session-Cookie认证是利用服务端的Session(会话)和浏览器(客户端)的 Cookie 来实现的前后端通信认证模式。
在理解这句话之前我们先简单了解下什么是 Cookie以及什么是 Session?
3.1 什么是 Cookie
众所周知,HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息);
所以为了让服务器区分不同的客户端,就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态可以通过Cookie去实现。
特点:
3.2 什么是 Session
Session 的抽象概念是会话,是无状态协议通信过程中,为了实现中断/继续操作,将用户和服务器之间的交互进行的一种抽象;
具体来说,是服务器生成的一种 Session 结构,可以通过多种方式保存,如内存、数据库、文件等,大型网站一般有专门的 Session 服务器集群来保存用户会话;
原理流程:
特点:
与 Cookie 的差异:
看到这里可能就有人想到了,Session-Cookie是不是就是把Session存储在了客户端的Cookie中呢?是的,的确是这样的,我们接着往下看
3.3 Session-Cookie 的认证流程图
3.4 Session-Cookie 认证步骤解析
注:可以使用签名对sid进行加密处理,服务端会根据对应的secret密钥进行解密 (非必须步骤)
3.5 Session-Cookie 优缺点对比
优点
缺点
3.6 使用场景
4、Token认证方案
现在我们已经得知,Session-Cookie的一些缺点,以及 Session 的维护给服务端造成很大困扰,我们必须找地方存放它,又要考虑分布式的问题,甚至要单独为了它启用一套 Redis 集群。那有没有更好的办法?
那Token就应运而生了
4.1 Token认证原理
Token是一个令牌,客户端访问服务器时,验证通过后服务端会为其签发一张令牌,之后客户端就可以携带令牌访问服务器,服务端只需要验证令牌的有效性即可。
一句话概括;访问资源接口(API)时所需要的资源凭证
一般 Token 的组成:
uid(用户唯一的身份标识) +time(当前时间的时间戳) +sign(签名,Token的前几位以哈希算法压缩成的一定长度的十六进制字符串)
Token 的认证流程图:
Token 认证步骤解析:
Token 的优点:
Token 的缺点:
4.2 刷新 Token
业务接口用来鉴权的 Token,我们称之为Access Token。
为了安全,我们的Access Token有效期一般设置较短,以避免被盗用。但过短的有效期会造成Access Token经常过期,过期后怎么办呢?
一种办法是:刷新 Access Token,让用户重新登录获取新 Token,会很麻烦;
另外一种办法是:再来一个 Token,一个专门生成 Access Token 的 Token,我们称为Refresh Token;
Refresh Token 的认证流程图:
Refresh Token 认证步骤解析:
4.3 Token 和 Session-Cookie 的区别
Session-Cookie和Token有很多类似的地方,但是Token更像是Session-Cookie的升级改良版。
如果你的用户数据可能需要和第三方共享,或者允许第三方调用API接口,用Token 。如果永远只是自己的网站,自己的App,用什么就无所谓了。
5、OAuth2.0认证方案
5.1 OAuth2.0定义
OAuth 2.0 是一个开放授权标准,它允许用户让第三方应用基于令牌Token的授权,在无需暴露用户密码的情况下使第三应用能获取对用户数据的有限访问权限 。
OAuth 2.0定义了四种授权许可类型:
5.2 OAuth2.0角色
(A)资源拥有者(RO)
(B)客户端(Client)
(C)资源服务器(RS)
(D)授证服务器(AS)。
5.3 OAuth2.0认证流程
5.3.1、OAuth 2.0流程图
关键步骤:
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)授权认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
5.3.2、授权码模式
授权码模式(authorization code)是功能最完整、流程最严密的授权模式。
它的特点就是通过客户端的后台服务器,与“服务提供商”的授权认证中心进行互动
关键步骤:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
说明备注:
第1步骤中,客户端申请认证的URI,包含以下参数:
response_type:表示授权类型,必选项,此处的值固定为"code"
client_id:表示客户端的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
5.3.2、隐式许可模式
隐式许可模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。
所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
关键步骤:
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
说明备注:
A步骤中,客户端发出的HTTP请求,包含以下参数:
response_type:表示授权类型,此处的值固定为"token",必选项。
client_id:表示客户端的ID,必选项。
redirect_uri:表示重定向的URI,可选项。
scope:表示权限范围,可选项。
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
5.3.3、密码凭证模式
密码凭证模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。
客户端使用这些信息,向"服务提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。
这通常用在用户对客户端高度信任的情况下,并且只有授权认证中心在其他授权模式无法执行的情况下,才能考虑使用这种模式。
关键步骤:
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
说明备注:
B步骤中,客户端发出的HTTP请求,包含以下参数:
grant_type:表示授权类型,此处的值固定为"password",必选项。
username:表示用户名,必选项。
password:表示用户的密码,必选项。
scope:表示权限范围,可选项。
5.3.4 客户端凭证模式
客户端凭证模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向授权认证中心进行认证。严格地说,客户端凭证模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
关键步骤:
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
备注说明:
A步骤中,客户端发出的HTTP请求,包含以下参数:
granttype:表示授权类型,此处的值固定为"clientcredentials",必选项。
scope:表示权限范围,可选项。
6、JWT Token验证
我们知道了Token的使用方式以及组成,我们不难发现,服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户基本信息,然后验证 Token 是否有效;
这样每次请求验证都要查询数据库,增加了查库带来的延迟等性能消耗;
那么这时候业界常用的JWT就应运而生了!!!
6.1 JWT定义
JWT是Auth0提出的通过对 JSON 进行加密签名来实现授权验证的方案;
就是登录成功后将相关用户信息组成 JSON 对象,然后对这个对象进行某种方式的加密,返回给客户端;客户端在下次请求时带上这个 Token;服务端再收到请求时校验 token 合法性,其实也就是在校验请求的合法性。
6.2 JWT 的组成
JWT 由三部分组成:Header 头部、Payload 负载和Signature 签名
它是一个很长的字符串,中间用点(.)分隔成三个部分。列如 :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header 头部:
在 Header 中通常包含了两部分:
{
"alg": "HS256",
"typ": "JWT"
}
Payload 负载:
它包含一些声明 Claim (实体的描述,通常是一个 User 信息,还包括一些其他的元数据) ,用来存放实际需要传递的数据,JWT 规定了7个官方字段:
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Signature 签名
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
JWT 加密、解密标例
6.3 JWT使用
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
Authorization: Bearer <token>
6.4 JWT认证流程
其实 JWT 的认证流程与 Token 的认证流程差不多,只是不需要再单独去查询数据库查找用户用户;简要概括如下:
6.5 JWT优缺点
优点:
缺点:
7、集团统一授权认证架构方案
首先感谢各位看官!文章很长,为了普及认证基本原理不得花重手笔详细描述清楚知识点。能一路看到这里,恭喜你!应该对认证体系有了系统性的了解和认识。
通过上面各种方案分析整理对比,我们已经有了一个清晰结构认知。下面我们来设计一套适用于集团内部的统一的授权认证方案。
我们集团内部有很多个业务系统包括(三大体系:职能、制造、营销):
职能系统:OA系统、商旅系统、财务系统、培训系统、BPM、ERP;
制造系统:MES、MLP、MOM、MSCS、WCC、MTCS、TIMS、SRM、WMS、PLM、......
营销系统:用户中心、设计软件、客服400系统、客情调查问卷、订单系统,账号系统、活动系统、促销系统、会员系统、CRM、电商引流、营销补贴、学习培训、传单系统等各种独立的业务中台和数据中台共有60多个子系统。
这些系统全部都要打通统一授权体系,实现单点登录。所以整体实施方案是比较复杂的。
当时在设计授权方案是遇到不小挑战,基于已有业务主要存在几个重要困难点:
1、集团内部已经有非常多个子系统,算下来大大小小有130多个子系统;
2、集团职能体系和制造体系已经有一套相对早期的基于CAS单点登录系统,而且很难改得动;
3、关键难搞的是只要涉及到财务和生产制造系统,保持系统稳定的指标压倒其他一切;
4、营销体系的各个系统相对比较新,采用Oauth2协议认证,实现营销体系内部统一认证。
虽然制造体系与营销体系系统相对独立,各有一个单点登录但还是不能满足业务的要求,两套认证体系各自为政,这是认人不可接受的。BOSS的目标是:集团内部所有系统一次登录必须互通互联。
7.1 集团认证方案设计
7.1.1 早期基于CAS集成SSO服务
整体逻辑概图
①用户请求访问业务系统。
②业务系统在系统中查看是否有对应请求的有效令牌,若有,则读取对应的身份信息,允许其访问;若没有或令牌无效,则把用户重定向到统一身份认证平台,并携带业务系统地址,进入第③步。
③在统一身份认证平台提供的页面中,用户输入身份凭证信息,平台验证此身份凭证信息,若有效,则生成一个有效的令牌给用户,进入第④步;若无效,则继续进行认证,直到认证成功或退出为止。
④用户携带第③步获取的令牌,再次访问业务系统。
⑤业务系统获取用户携带的令牌,提交到认证平台进行有效性检查和身份信息获取。
⑥若令牌通过有效性检查,则认证平台会把令牌对应的用户身份信息返回给业务系统,业务系统把身份信息和有效令牌写入会话状态中,允许用户以此身份信息进行业务系统的各种操作;若令牌未通过有效性检查,则会再次重定向到认证平台,返回第③步。
通过统一身份认证平台获取的有效令牌,可以在各个业务系统之间实现应用漫游。
SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。如果通过效验,用户就可以在不用再次登录的情况下访问其他子系统。
sso的实现技术点:
1)所有应用系统共享一个身份认证系统。
统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。
2)所有应用系统能够识别和提取ticket信息
要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
基于CAS PC端认证流程时序图
SSO采用是开源cas单点登录系统,在java web系统集成比较方便,也就是说,我们在jsp方面是基本不用做太大改动的,需要修改认证方式,以及需要验证票据等为数不多的修改。但是针对于移动端或是前后端分离的系统,需要做一些改造设计。
下面对每个场景做单独阐述
一、在jsp下场景的应用,这个时候我们需要修改handler、resolver,如果是在http协议上工作的,那么一定要允许http才行,不然默认不支持单点登录,handler处理登录请求,以工作流的方式作为时间驱动,一步一步的进行单点登录验证以及tgt、st的处理。
二、移动端的认证方式,(Android、iOS)原理是一样的,移动端在本地是有一个小型的关系数据库,叫做sqllite,不过这个关系数据库比较小,就像一个文件夹似的内置,因为移动端本身并没有像我们web端的cookie机制,所以我们使用这个sqlite作为票据存储。
基于CAS 移动端认证流程时序图
工作步骤如下:
1、在手机端的登录页,提交用户名、密码至sso服务器
2、认证通过、返回tgt,然后本地存储这个tgt
3、请求st、并且以上一步请求到的tgt作为参数
4、sso服务器返回st
5、移动端访问业务系统,并且携带st作为参数
6、业务系统接收到请求,会向sso服务器校验st是否有效
7、若有效,则返回该用户信息,若无效,即此次登录无效
基于CAS关键类图
基于CAS集成存在的问题:
1、移动端集成起比较复杂和繁琐。
2、在实际生产使用过程当经常出现tgt串号的问题,多次被业务方投诉。
3、性能问题,随着接入系统越来越多,认证中点不堪其负,出现压力故障。
4、营销体系的CAS产生的TGT与制造体系没有互信机制,两边体系需要多次登录,使用非常麻烦。
7.1.2 基于OAuth2集成认证中心
营销体系与其他外部的集成示例
营销体系Oauth2认证方案
统一授权认证中心时序图
经过微服务SpringCloud体系升级改造,统一认证中心集成了gateway,授权服务authorization,鉴权服务authentication,其时序图如下所示:
关键步骤:
1、用户客户端所有请求都先经过网关gateway(如前后端分离设计的API请求);
2、网关转发到授权服务,请求生成系统token和accessToken;
3、用户发起API请求,先经过网关系统token验证,通过才能进入下一步;
4、网关通过后,拿accessToken调用鉴权服务请求鉴权,鉴权通过,转发到真正的业务服务去;
5、业务服务返回API请求结果。
营销体系授权认证中心与集团SSO认证中心两套体系互认示例
7.2 关键问题
授权认证中心主要提供四个端点:认证端点、令牌颁发端点、令牌校验端点和注销端点。
集团内部CAS单点与营销系统Oauth2.0认证内部打通隧道建立互信机制。
1、用户登录职能或制造系统在CAS认证通过,发起一次营销系统的Oauth2认证服务消息通知,并完成一次授信;
2、用户登录营销系统在oauth2认证服务鉴权通过,发起一次CAS通讯通过用户关键信息进行TGT交换,并做一次token和tgt绑定动作。
3、用户在任意一个体系注销,两边系统都会互发一次消息通知。
通过上次机制设计实现了两套独立认证体系互通互信。不用修改原有旧系统登录逻辑,也是最少代价方案实现全集团系统单点登录 。
7.3 核心代码实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。