「码动四季·开源同行」go语言:统一认证与授权如何保障服务安全
认证与授权对于当前的互联网应用是非常重要的基础功能认证用于验证当前用户的身份而授权意味着用户在认证成功后会被系统授予访问系统资源的权限。只有具备相应身份和权限的人才能访问系统中的相应资源比如在购物网站中你只能支付你自己购物车内的商品这就保护了用户和系统的信息安全。微服务架构不同于单体应用的架构单体应用的认证和授权非常集中但是当服务被拆分之后对各个微服务的认证与授权就会变得非常分散因此在微服务架构中就将集成统一认证与授权的功能作为横切关注点为应用服务提供信息安全保障。微服务安全的挑战和现状在单体应用中开发者可以通过简单的拦截器以及 Session 机制对用户的访问进行控制和记录。但是在目前微服务盛行的架构体系下服务的数量在业务分解后急剧增加其中每个微服务都需要对用户的行为进行认证和许可明确当前访问用户的身份与权限级别。与此同时整个系统可能还需对外提供一定的服务比如第三方登录授权等。在这种情况下如果要求每个微服务都实现各自的用户信息管理系统那不仅增加了开发的工作量而且出错的概率也会大大增加。对此而言统一的认证与授权就显得尤为必要和有效了。目前主流的统一认证和授权方式有 OAuth2、分布式 Session 和 JWT 等其中又以 OAuth2 方案使用最为广泛已经成为当前授权的行业标准。由于统一认证与授权方案会将用户信息进行统一管理和使用这就很可能出现系统性能瓶颈的问题甚至在认证和授权服务宕机后整个系统将无法正常运行。与此同时整合当前系统中各个服务的用户信息管理系统也存在一定的难度所以在实践时需要根据项目的现状理智选择统一认证与授权方案。常见的认证与授权方案有 OAuth2、分布式 Session 和JWT 等下面我们就来分别介绍这 3 种方案看看这些方案是如何保障微服务安全的。当前行业授权标准OAuth2OAuth 协议目前已经发展到OAuth2 版本之前的OAuth1由于不被 OAuth2 兼容且签名逻辑过于复杂和授权流程过于单一所以这里我们就不过多讨论它。下面我们重点关注的是 OAuth2认证流程它是当前Web应用中的主流授权流程。OAuth2是当前授权的行业标准其重点在于为Web应用程序、桌面应用程序、移动设备以及室内设备的授权流程提供简单的客户端开发方式。它为第三方应用提供对HTTP服务的有限访问既可以是资源拥有者通过授权允许第三方应用获取HTTP服务也可以是第三方应用以自己的名义获取访问权限。接下来我们会首先介绍OAuth2 协议的参与角色然后阐述OAuth2 协议认证授权的基本流程最后再对OAuth2中客户端授权类型进行讲解1.角色OAuth2中主要分为了4种角色如下表所示在多数情况下资源服务器和授权服务器是合二为一的在授权交互时是授权服务器在请求资源交互时是资源服务器。当授权服务器是单独的实体时它可以发出被多个资源服务器接受的访问令牌。2.协议流程我们来看一张OAuth2的流程图如下这是一张关于OAuth2角色的抽象交互流程图主要包含以下6个步骤。①客户端请求资源所有者的授权。②资源所有者同意授权返回授权许可AuthorizationGrant这代表了资源所有者的授权凭证。③客户端携带授权许可要求授权服务器进行认证请求访问令牌。④授权服务器会同时验证客户端身份和认证客户端携带的授权许可的有效性如果有效则返回访问令牌。⑤客户端获取到授权服务器颁发的访问令牌后就可以携带访问令牌访问资源服务器中受保护的资源。⑥资源服务器验证访问令牌如果有效则接受访问请求返回受保护资源。3.客户端授权类型客户端只有在获取到资源所有者的授权许可后才能向授权服务器请求访问令牌。OAuth2 默认定义了4 种授权类型当然也提供了用于定义额外的授权类型的扩展机制。默认的4种授权类型如下表所示:其中经常使用的授权类型为授权码类型和密码类型。简化类型是由于省略了授权码类型流程中的授权码步骤而得名而客户端类型是客户端以自己的名义直接向授权服务器请求访问令牌不需要用户授权即可请求访问令牌。我们接下来就只对常用的授权码类型和密码类型的流程做详细的介绍。1授权码类型授权码类型是 OAuth2 默认授权类型中功能最完整、流程最严密的授权类型。授权码类型要求客户端能够与资源所有者的代理如Web 浏览器等进行交互它通过重定向资源所有者的代理让资源所有者与授权服务器直接交互授权避免资源所有者的信息被泄漏并将授权通过后生成的授权码以重定向的方式返回给客户端。其授权流程图如下图所示:结合该流程图我们来分析一下授权码类型的整个工作流程。①客户端将资源所有者的代理重定向到授权服务器的端点客户端会在重定向的地址中提交自身的客户端标识、请求范围、本地状态和用于接收授权码的重定向地址等信息。②资源所有者通过代理与授权服务器直接交互授权服务器认证资源所有者的身份并确认资源所有者同意还是拒绝访问授权。③在资源所有者同意授予客户端访问权限后授权服务器会回调客户端在第一步中提交的重定向地址并在重定向地址中携带生成的授权码和原先提交的本地状态。否则直接返回资源所有者拒绝授权。④获取到授权码的客户端可以携带授权码和用于获取授权码的重定向地址向授权服务器请求访问令牌。授权服务器会对客户端身份和授权码同时进行认证。⑤授权服务器认证客户端身份和授权码并对客户端提交的重定向地址和获取授权码的重定向地址进行匹配。如果信息一致则返回访问令牌并有可能同时返回刷新令牌。(2密码类型在密码类型中资源所有者会将自身的密码凭证直接交予客户端客户端通过自己持有的信息直接从授权服务器获取授权。在这种情况下需要资源所有者对客户端高度信任同时客户端不允许保存密码凭证。这种授权类型适用于能够获取资源所有者凭证如用户名和密码的客户端。授权流程图如下所示同样我们还结合授权流程图来分析一下密码类型的授权流程。①资源所有者向客户端提供其用户名和密码等凭证。②客户端携带资源所有者的凭证用户名和密码向授权服务器请求访问令牌。③授权服务器认证客户端身份和携带的资源所有者凭证如果有效则返回访问令牌并可能同时返回刷新令牌。(3刷新令牌以上两种类型中你可能也注意到了响应结果中可能会同时返回刷新令牌。那什么是刷新令牌呢刷新令牌是授权服务器提供给客户端在访问令牌失效时重新向授权服务器申请访问令牌的凭证。客户端从授权服务器中获取的访问令牌一般是具备时效性的在访问令牌过期的情况下持有有效用户凭证的客户端可以再次向授权服务器请求访问令牌而持有刷新令牌的客户端也可以向授权服务器请求新的访问令牌也就是令牌刷新操作。数据共享的分布式Session在Web服务盛行的当下我们一般会通过 Session 和 Cookie 来维护访问用户的登录状态。同时随着分布式系统的快速发展原本在单个服务器上的 Session 管理也逐渐发展为分布式 Session 管理。接下来我们就来介绍会话跟踪技术 Session 和 Cookie以及分布式 Session 的作用和相关实现方案。1.会话跟踪技术 Session 和 Cookie会话是指用户登录网站后的一系列操作比如查看列表、收藏商品和购买商品等。一次会话中一般会存在多次的HTTP请求。而HTTP 协议作为一种无状态协议在连接关闭之后服务器就无法继续跟踪用户的会话从而丢失了用户操作的上下文信息。对此我们需要会话跟踪技术管理和跟踪用户的整个会话在多次HTP操作中将用户与用户关联起来。而Session 和Cookie就是最常用的会话跟踪技术。Session 和Cookie 是一种记录用户状态信息的机制它们分别被保存在服务器端和客户端浏览器中。当客户端浏览器访问服务器的时候服务器会把当前的用户信息以某种形式记录在服务器上这就是Session。客户端浏览器在访问时可以通过 Session 查找该用户的状态。Cookie 实际上是在客户端浏览器请求服务器时如果服务器需要记录当前用户的状态就会在响应中向客户端浏览器颁发一小段的文本信息用于标记当前的用户状态这段文本信息与服务器中的 Session一一对应被称为Cookie。当浏览器再次请求该网站时会把请求的网址连同该Cookie 提交给服务器。服务器根据 Cookie 中的信息查找 Session从 Session中获取用户信息以此来辨认用户状态。服务器还可以根据需要修改 Cookie 中的内容。简单来说Cookie 被用在客户端中记录用户身份信息而 Session 被用在服务器端中记录用户身份信息。2.分布式 Session 的作用在单体应用时代应用部署在同一个Web 服务器上可以使用同一个Web服务器对 Session 进行管理。随着系统架构的演进在分布式架构或者微服务架构中会存在多个Web 服务器用户的请求根据负载均衡转发到不同的机器上这就有可能导致Session 丢失的情况出现。比如一开始用户在A机器上登录并发起请求后来由于负载均衡请求被转发到B机器上那这时会出现什么问题呢因为用户的 Session保存在A机器的Web服务器上在B 机器的Web服务器上是无法查找到的所以导致Β机器认为用户没有登录返回了用户末登录的异常引起了用户的费解。因此在分布式架构或微服务架构下就需要保证在一个Web 服务器上保存 Session后其他 Web服务器可以同步或共享这个 Session达到用户一次登录、多处可访问的效果。这就是分布式 Session 要做的事。3.分布式Session的实现方案分布式 Session 有如下几种实现方式如下表所示:综合对比这4种方式相对来说集中式管理更加可靠也是应用最广泛的。安全传输对象JWTJWTJSONWebToken作为一个开放的标准通过紧凑快速传输体积小并且自包含有效负载中包含用户所需的所有信息避免了对数据库的多次查询的方式定义了用于在各方之间发送的安全JSON对象。JWT可以很好地充当 OAuth2 的访问令牌和刷新令牌的载体这是 Web 双方之间进行安全传输信息的良好方式。当只有授权服务器持有签发和验证 jJWT的 secret时也就只有授权服务器能验证 JWT的有效性以及签发带有签名的JWT这就保证了以JWT为载体的Token的有效性和安全性。JWT格式一般如下:eyJhbGcioiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYWl1IjoiY2FuZyB3dSIsImV4cCI6MTUxODA1MTE1NywidXN1ck1kIjoiMTIzNDU2In0.IV4XZ0y0nMpmMX9orv0gqsEMOxXXNQOE680CKkkPQcs它由 3 部分组成每部分通过.分隔开分别是Header头部、Payload有效负载和Signature签名。接下来我们就对每一部分进行详细的介绍。1.Header(头部)头部通常由两部分组成。typ类型一般为JWT。alg加密算法通常是 HMAC SHA256 或者 RSA。一个简单的头部例子如下{ alg : HS256 typ : JwT }这部分JSON 数据会使用 Base64Url 编码后用于构成JWT的第一部分如下所示:eyJhbGcioiJIUzI1NiIsInR5cCI6IkpXVCJ92. Playload(有效负载)有效负载是JⅧT的第二部分是用来携带有效信息的载体主要是关于用户实体和附加元数据的声明由以下3部分组成。Registered claims注册声明。它是jWT预定的声明但通常不要求强制使用。主要包含issJWT 签发者、expJWT过期时间、subJWT 面向的用户、aud接受jWT的一方)等属性信息。Public claims公开声明。在公开声明中可以添加任何信息一般是用户信息或者业务扩展信息等。Private claims私有声明。它是由jWT提供者和消费者共同定义的声明既不属于注册声明也不属于公开声明。Base64 对称解密的方式很容易使得加密信息被还原所以一般不建议在 Payload 中添加任何的敏感信息。一个简单的有效负载例子如下{ sub: 1234567890, name: xuan, exp: 1518051157 }这部分JSON 会使用 Base64Url 编码后用于构成JWT的第二部分如下所示:eyJzdwIioiIxMjMONTY3oDkwIiwibmFtZSI6Inh1YW4iLCJ1eHAiojE1MTgwNTExNTd93. Signature (签名)要创建签名就必须要有被编码后的头部、被编码后的有效负载以及一个 secret最后通过在头部定义的加密算法 alg 加密生成签名。生成签名的伪代码如下HMACSHA256( base64urlEncode(header) . base64urlEncode(payload) , secret)上述伪代码中使用的加密算法为HMACSHA256。Secret作为签发密钥用于验证JWT以及签发JWT所以只能由服务端持有不该泄漏出去。一个简单的签名如下这就是WT的第三部分。X36pDQoYydHv7KDCi1tTBKcQbt-iIT-jFgmUjkTSCxE如上所述的三个部分通过.分割就组成最终的WT。小结在本文中我们围绕统一认证与授权如何去保障服务安全依次介绍了OAuth2、分布式 Session 和JMT等认证与授权方案这其中以OAuth2方案最为标准和完备。希望通过本文的学习能够帮助你建立对微服务架构下统一认证和授权方案的宏观认知。在接下来我们将采用Go语言并基于OAuth2 协议和JWT实现一个简单的认证和授权系统让你熟练掌握如何在微服务架构中对用户的资源进行保护。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2472532.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!