各位读者朋友鼠年大吉,祝各位新的一年身体健康,万事如意!
最近疫情严重,是一个特殊时期,大家一定要注意防护。很多省份推迟了企业开工的时间,大部分的互联网公司也都是下周开始远程办公。大家可以利用在家的几天时间学习充电,反正也出不去(🙂🙂🙂)。
今天笔者要写得是 Go 微服务相关的组件实践,笔者在好几年前就接触 Go 语言,去年开始从事 Go 微服务相关的开发,在过程中也和小伙伴联合编写了一本 《Go 高并发与微服务实战》书籍,即将出版上市。本文是截取其中的抢先版阅览,介绍微服务统一认证与授权的 Go 语言实现。
1 前言
统一认证与授权是微服务架构的基础功能,微服务架构不同于单体应用的架构,认证和授权非常集中。当服务拆分之后,对各个微服务认证与授权变得非常分散,所以在微服务架构中,将集成统一认证与授权的功能,作为横切关注点。
2 常见的认证与授权方案
常见的认证与授权方案有 OAuth、分布式 Session、OpenID 和 JWT 等,下面我们将分别介绍这四种方案。
2.1 OAuth
OAuth2 相关理论的介绍主要来自于OAuth2官方文档,相关地址为https://tools.ietf.org/html/rfc6749
。
OAuth 协议的目的是为了为用户资源的授权提供一个安全的、开放而简易的标准。官网中的介绍如下:
An open protocol to allow secure API authorization in a simple and standard method from web, mobile and desktop applications.
OAuth1 由于不被 OAuth2 兼容,且签名逻辑过于复杂和授权流程的过于单一,在此不过多谈论,以下重点关注OAuth2认证流程,它是当前Web应用中的主流授权流程。
OAuth2是当前授权的行业标准,其重点在于为Web应用程序、桌面应用程序、移动设备以及室内设备的授权流程提供简单的客户端开发方式。它为第三方应用提供对HTTP服务的有限访问,既可以是资源拥有者通过授权允许第三方应用获取HTTP服务,也可以是第三方以自己的名义获取访问权限。
角色
OAuth2 中主要分为了4种角色
- resource owner 资源所有者,是能够对受保护的资源授予访问权限的实体,可以是一个用户,这时会被称为end-user。
- resource server 资源服务器,持有受保护的资源,允许持有访问令牌(access token)的请求访问受保护资源。
- client 客户端,持有资源所有者的授权,代表资源所有者对受保护资源进行访问。
- authorization server 授权服务器,对资源所有者的授权进行认证,成功后向客户端发送访问令牌。
在很多时候,资源服务器和授权服务器是合二为一的,在授权交互的时候是授权服务器,在请求资源交互是资源服务器。但是授权服务器是单独的实体,它可以发出被多个资源服务器接受的访问令牌。
协议流程
首先看一张来自官方提供的流程图:
+--------+ +---------------+
| |--(1)- Authorization Request ->| Resource |
| | | Owner |
| |<-(2)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(3)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(4)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(5)----- Access Token ------>| Resource |
| | | Server |
| |<-(6)--- Protected Resource ---| |
+--------+ +---------------+
这是一张关于OAuth2角色的抽象交互流程图,主要包含以下的6个步骤:
- 客户端请求资源所有者的授权;
- 资源所有者同意授权,返回授权许可(Authorization Grant),这代表了资源所有者的授权凭证;
- 客户端携带授权许可要求授权服务器进行认证,请求访问令牌;
- 授权服务器对客户端进行身份验证,并认证授权许可,如果有效,返回访问令牌;
- 客户端携带访问许可向资源服务器请求受保护资源的访问;
- 资源服务器验证访问令牌,如果有效,接受访问请求,返回受保护资源。
客户端授权类型
为了获取访问令牌,客户端必须获取到资源所有者的授权许可。OAuth2默认定了四种授权类型,当然也提供了用于定义额外的授权类型的扩展机制。默认的四种授权类型为:
- authorization code 授权码类型
- implicit 简化类型(也称为隐式类型)
- resource owner password credentials 密码类型
- client credential 客户端类型
下面对常用的授权码类型和密码类型进行详细的介绍。
授权码类型
授权码类型(authorization code)通过重定向的方式让资源所有者直接与授权服务器进行交互来进行授权,