OAuth2协议
1. oauth2协议介绍及认证流程
首先声明oauth2是一种协议规范,OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。"客户端"不能直接登录"服务提供商",只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。"客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。
spring-security-oauth2是对他的一种实现。oauth生态设计的范围很大,可以说是一种解决方案,它有“第三方客户端(web服务,APP服务)”、“用户”、“认证服务器”、“资源服务器”等部分。认证流程如下图:
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
2. oauth2根据使用场景不同,分成了4种模式
-
授权码模式(authorization code)
-
简化模式(implicit)
-
密码模式(resource owner password credentials)
-
客户端模式(client credentials)
分布式认证分析
1. 分布式认证需求
分布式系统的每个服务都会有认证、授权的需求,如果每个服务都实现一套认证授权逻辑会非常冗余,考虑分布式系统共享性的特点,需要由独立的认证服务处理系统认证授权的请求;考虑分布式系统开放性的特点,不仅对系统内部服务提供认证,对第三方系统也要提供认证。分布式认证的需求总结如下:
1)统一认证授权
提供独立的认证服务,统一处理认证授权。
无论是不同类型的用户,还是不同种类的客户端(web端,H5、APP),均采用一致的认证、权限、会话机制,实现统一认证授权。
要实现统一则认证方式必须可扩展,支持各种认证需求,比如:用户名密码认证、短信验证码、二维码、人脸识别等认证方式,并可以非常灵活的切换。
2)应用接入认证
应提供扩展和开放能力,提供安全的系统对接机制,并可开放部分API给接入第三方使用,一方应用(内部 系统服务)和三方应用(第三方应用)均采用统一机制接入。
2. 分布式认证方案
1)基于Session的认证方式
在分布式的环境下,基于session的认证会出现一个问题,每个应用服务都需要在session中存储用户身份信息,通过负载均衡将本地的请求分配到另一个应用服务需要将session信息带过去,否则会重新认证。
这个时候,通常的做法有下面几种:
① Session复制:多台应用服务器之间同步session,使session保持一致,对外透明
② Session黏贴:当用户访问集群中某台服务器后,强制指定后续所有请求均落到此机器上。
③ Session集中存储:将Session存入分布式缓存中,所有服务器应用实例统一从分布式缓存 中存取Session。
总体来讲,基于session认证的认证方式,可以更好的在服务端对会话进行控制,且安全性较高。但是,session机制方式基于cookie,在复杂多样的移动客户端上不能有效的使用,并且无法跨域,另外随着系统的扩展需提高session的复制、黏贴及存储的容错性。
2)基于token的认证方式
基于token的认证方式,服务端不用存储认证数据,易维护扩展性强, 客户端可以把token 存在任意地方,并且可以实现web和app统一认证机制。其缺点也很明显,token由于自包含信息,因此一般数据量较大,而且每次请求都需要传递,因此比较占带宽。另外,token的签名验签操作也会给cpu带来额外的处理负担。
在分析完这两种认证方式之后,决定采用基于token的认证方式,它的优点更符合我们分布式认证方案:
① 适合统一认证的机制,客户端、一方应用、三方应用都遵循一致的认证机制
② token认证方式对第三方应用接入更适合,因为它更开放,可使用当前有流行的开放协议 Oauth2.0、JWT等
③ 一般情况服务端无需存储会话信息,减轻了服务端的压力。
3. 分布式系统认证技术方案及流程
分布式系统认证技术方案见下图:
流程描述:
(1)用户通过接入方(应用)登录,接入方采取OAuth2.0方式在统一认证服务(UAA)中认 证。
(2)认证服务(UAA)调用验证该用户的身份是否合法,并获取用户权限信息。
(3)认证服务(UAA)获取接入方权限信息,并验证接入方是否合法。
(4)若登录用户以及接入方都合法,认证服务生成jwt令牌返回给接入方,其中jwt中包含了 用户权限及接入方权限。
(5)后续,接入方携带jwt令牌对API网关内的微服务资源进行访问。
(6)API网关对令牌解析、并验证接入方的权限是否能够访问本次请求的微服务。
(7)如果接入方的权限没问题,API网关将原请求header中附加解析后的明文Token,并将 请求转发至微服务。
(8)微服务收到请求,明文token中包含登录用户的身份和权限信息。因此后续微服务自己 可以干两件事:
① 用户授权拦截(看当前用户是否有权访问该资源)
② 将用户信息存储到当前线程的上下文(有利于后续业务逻辑随时能获取到当前 登录用户信息)
流程所涉及到UAA服务、API网关这三个组件职责如下:
① 统一认证服务(UAA),它承载了OAuth2.0接入方认证、登入用户的认证、授权 以及生成令牌的职责,完成实际的用户认证、授权功能。
② API网关,作为系统的唯一入口,API网关为接入方提供定制的API集合,它可能 还具有其它职责,如身份验证、监控、负载均衡、缓存等。API网关方式的核心 要点是,所有的接入方和消费端都通过统一的网关接入微服务,在网关层处理所 有的非业务功能。