转自:http://www.primeton.com/read.php?id=2667&his=1

引言:

微服务大行其道,微服务安全也是非常热门的话题。本文向大家分享微服务系统中认证管理相关技术。其中包括用户认证、网关和 API 认证、系统间和系统内的认证,以及我们的统一认证管理系统 IAM。

目录:
一、简介
二、用户认证
三、网关及API调用认证
四、系统间认证和系统内认证
五、总结

一、简介

首先,我们来看一下什么是认证?

认证是确认当前声称为 xxx 的用户确实为 xxx 本身。

用户可以是人、系统、应用或任意调用者。

 

最简单的认证,就是用户名密码登录,常见的认证方式还有:手机验证码、生物识别(指纹,虹膜识别、面部识别等)、U 盾、数字证书。

关于认证更加详尽的定义和认证方式,请参见维基百科:https://en.wikipedia.org/wiki/Authentication

那在微服务系统中有哪些地方需要进行认证管理(不包括DevOps中的认证)呢?如下图所示:


凡是存在交互的地方均需要进行认证:

用户访问系统

系统调用网关

网关调用系统

系统内应用之间的调用

系统间的调用

可以将它们分为如下三类:

用户认证

系统间及系统内认证

网关及 API 调用认证

下面我们将对这三类认证,分别做详细的介绍。

二、用户认证

微服务架构中会存在很多系统,而且系统间的切换也需要无缝进行,例如一个前端框架中可能会集成多个系统的调用。此时,我们自然而然的会想到单点登录,单点登录早在已存在。但微服务中的单点登录与传统的单点登录有一定的差异。

下面这幅图描述传统的基于 Session 的单点登录。

用户的授权信息(例如角色,可访问资源等)保存在应用的 session 中,浏览器与应用系统之间基于sessionID 关联,相同应用的集群使用缓存(如 Redis、memcached 等),或基于 session 复制来进行共享 session 信息。

但是微服务系统中,api 的调用都是 stateless,没有状态信息,如下图所示:

用户的授权信息通常直接封装到 token 中,用户在访问应用或系统的时候,携带上 token,应用或系统直接从 token 中反解出用户的授权相关信息

2.1.OAuth2.0与SSO

OAuth2.0是授权框架,SSO 是认证服务,但是我们可以基于 OAuth2.0实现SSO 认证服务。

OAuth2.0本身不提供认证服务,但是具有足够的扩展空间,让我们来扩展,例如基于 OAuth2.0 的OIDC。

2.2.基于OAuth2.0的单点登录

上图所示,为一个基于OAuth2.0的 SSO的流程,整体流程基本上和普通的 SSO 一致,所不同的是,存储 app Cookie 的时候,保存的是经过应用或系统处理和加密过的 token,用户后续请求,带上加密后的 token,在 app 后端直接解密和抽取出用户相关的授权信息,流程如下:

1. 用户访问app1.com
2. 由于用户没有登录,因此跳转到 iam.com
3. 用户在 iam.com的登录页面,输入用户名和密码,确认提交,iam 校验成功后
4. 在浏览器端写入浏览器cookie
5. 重定向到 app1.com,并获取 token(此处获取 token流程,与OAuth2.0协议有关)
6.app1.com检查 token 有效性
7. 重定向用户访问页面,并存储 app1.com的token 到app1.com的cookie 中
8. 用户访问app2.com
9.app2.com重定向到iam.com
10.iam.com此时发现 cookie 内已经有认证的token(或 session) 信息
11. 直接重定向到app2.com,并获得 token 信息
12.app2.com验证 token 信息
13. 重定向到app2.com,并保存app2.com的 token 信息到 app2.com 的 cookie 中

2.3.Token

通常情况下,IAM会使用类似jwt 这样的协议去封装用户信息和授权相关信息。

App需要对 Token 进行处理,加密后再存入到浏览器 cookie 中去。

2.4.单点退出

传统的 SLO 是由 SSO 服务器通知每一个应用系统,强制 session失效。
在微服务系统中,由于系统或应用间调用是无状态的,因此 IAM 无法通知每个应用退出指定用户。

但是,我们可以利用 OAuth2.0 的refreshToken 机制,当app去refreshToken的时候,通知应用退出。

首先,当一个应用点击退出时,应用先通知 IAM 清除当前用户在 IAM 上的session 和所有相关的认证 Token 信息。

当其他应用进行refreshToken的时候,返回用户已经退出的信息,要求用户重新登录。

注意:这样的单点退出不是实时的,会存在一个误差(accessToken的有效时间)

2.5.用户登录控制

基于OAuth2.0 实现的 SSO,可以对用户是否可以登录某一系统进行控制。

在系统去交换/获取 Token的时候,判断用户是否具有访问指定系统的权限。

特点:可在线控制用户访问或拒绝访问指定系统。

缺点:同样不是实时的,会存在一个误差(accessToken的有效时间)。

2.6.在线用户管理


当用户登录IAM 的时候,IAM 可以跟踪和控制用户登录的超时。

当用户使用 SSO“登录”一个应用或系统时,会记录用户的 Token 信息。这里需要说明一下,用户的同一账号,有时候是可以同时在不通的机器上进行登录的。

通过控制“用户登录和系统授权”信息,来强制当前用户下线和统计在线用户信息和登录系统的信息。

三、网关及 API 调用认证

网关管理员

网关管理员访问网关系统,属于用户认证,则可以使用用户认证的方式来进行认证

API 调用

API调用认证可以绑定一组 API 到一个随机的 Token,使用Token 来唯一标识其绑定的一组 API 的访问权限,我们可以在系统中对这个 token 进行分配配额和 API 调用的限制;

注意:Token本身是不绑定调用者,所以,任何拥有 token 的应用都可以进行访问。

网关调用系统

网关调用系统,可以按照系统间的调用进行处理,请参见随后章节,系统间的调用。

四、系统间认证和系统内认证

系统间认证和系统内认证,实际上都是应用之间的调用,所不同的是,前者的应用是跨系统的,后者是在同一个系统内。

 

应用间的调用认证,可以对系统信息、应用信息、调用相关信息进行编码(jwt) 加密(jwe), 然后再通过http header的方式传输到下游系统或应用,下游系统或应用通过解密,获得调用者的相关信息,对其进行认证处理。

 

五、总结

认证管理有很多不同的方式,上面我所说的是一些常见的处理手段,也是普元统一认证管理平台IAM目前使用到的一些技术手段。

(IAM功能结构图)

(IAM部署结构图)

以上我们重点介绍了用户管理、SSO、SLO、网关及 API 调用认证、系统间和系统内认证及相关的处理技术。

当然,认证管理还有很多其他的处理手段和相关协议,比如认证授权协议: OIDC、SAML等,这里就不赘述了,有机会再和大家探讨。

参考内容

https://auth0.com/blog/what-is-and-how-does-single-sign-on-work/

https://searchsecurity.techtarget.com/definition/single-sign-on

https://en.wikipedia.org/wiki/Single_sign-on

https://spin.atomicobject.com/2016/05/30/openid-oauth-saml/

https://www.mutuallyhuman.com/blog/2013/05/09/choosing-an-sso-strategy-saml-vs-oauth2/

https://blog.heroku.com/oauth-sso

https://mp.weixin.qq.com/s/x0CZpovseOuofTA_lw0HvA