微服务化改造系列之四:授权中心

923
原文链接: mp.weixin.qq.com

前情概要:

授权中心概述

这篇文章是微服务化改造系列的第四篇,主题是授权中心。有了服务注册中心和配置中心,下一步应该就可以发起服务调用了吧?Wait, 还有一个关键问题要解决。不同于单体应用内部的方法调用,服务调用存在一个服务授权的概念。打个比方,原本一家三兄弟住一屋,每次上山打猎喊一声就行,后来三兄弟分了家,再打猎就要挨家挨户敲门了。这一敲一应就是所谓的服务授权。

严格来说,服务授权包含鉴权(Authentication)和授权(Authorization)两部分。鉴权解决的是调用方身份识别的问题,即敲门的是谁。授权解决的是调用是否被允许的问题,即让不让进门。两者一先一后,缺一不可。为避免歧义,如不特殊指明,下文所述授权都是宽泛意义上的授权,即包含了鉴权。

常见的服务授权有三种,简单授权,协议授权和中央授权。

  • 简单授权:服务提供方并不进行真正的授权,而是依赖于外部环境进行自动授权,比如IP地址白名单,内网域名等。这就好比三兄弟互相留了一个后门。

  • 协议授权:服务提供方和服务调用方事先约定一个密钥,服务调用方每次发起服务调用请求时,用约定的密钥对请求内容进行加密生成鉴权头(包含调用方唯一识别ID),服务提供方收到请求后,根据鉴权头找到相应的密钥对请求进行鉴权,鉴权通过后再决定是否授权此次调用。这就好比三兄弟之间约定敲一声是大哥,敲两声是二哥,敲三声是三弟。

  • 中央授权:引入独立的授权中心,服务调用方每次发起服务调用请求时,先从授权中心获取一个授权码,然后附在原始请求上一起发给服务提供方,提供方收到请求后,先通过授权中心将授权码还原成调用方身份信息和相应的权限列表,然后决定是否授权此次调用。这就好比三兄弟每家家门口安装了一个110联网的指纹识别器,通过远程指纹识别敲门人的身份。

一般来说,简单授权在业务规则简单、安全性要求不高的场景下用的比较多。而协议授权,比较适用于点对点或者C/S架构的服务调用场景,比如Amazon S3 API。对于网状结构的微服务而言,中央授权是三种方式中最适合也是最灵活的选择:

  1. 简化了服务提供方的实现,让提供方专注于权限设计而非实现。

  2. 更重要的是提供了一套独立于服务提供方和服务调用方的授权机制,无需重新发布服务,只要在授权中心修改服务授权规则,就可以影响后续的服务调用。

OAuth

说起起具体的授权协议,很多人第一反应就是OAuth。事实上也的确如此,很多互联网公司的开放平台都是基于OAuth协议实现的,比如Google APIs、微信网页授权接口。一次标准的OAuth授权过程如下:


对应到微服务场景,服务提供方相当于上图中的Resource Server,服务调用方相当于Client,而授权中心相当于Authorization Server和Resource Owner的合体。

想了解更多关于OAuth的信息,可移步OAuth2(http://oauthlib.readthedocs.io/en/latest/oauth2/oauth2.html)或者OAuth2中文版(http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)。

Beared Token

在标准的OAuth授权过程中,Resource Server收到Client发来的请求后,需要到Authorization Server验证Access Token,并获取Client的进一步信息。通过OAuth 2.0版本引入中的Beared Token,我们可以省去这一次调用,将Client信息存入Access Token,并在Resource Server端完成Access Token的鉴权。主流的Beared Token有SAML和JWT两种格式,SAML基于XML,而JWT基于JSON。由于大多数微服务都使用JSON作为序列化格式,JWT使用的更为广泛。

框架选型

在选型OAuth框架时,我主要调研了CAS、Apache Oltu、Spring Security OAuth和OAuth-Apis,对比如下:


不考虑实际业务场景,CAS和Spring Security OAuth相对另外两种框架,无论是集成成本还是可扩展性,都有明显优势。前文提到,由于我们选用了Spring Boot作为统一的微服务实现框架,Spring Security OAuth是更自然的选择,并且维护成本相对低一些(服务端)。

最终方案

最终我们基于Spring Security OAuth框架实现了自己的服务授权中心,鉴权部分做的比较简单,目前只支持私网认证。大致的服务授权流程如下:



值得一提的是,除了服务调用,我们的服务授权中心还增加了SSO的支持,通过微信企业号实现各个服务后台的单点登录/登出,以后有机会再详细介绍。

冰山一角

至此,这个微服务化改造系列就算告一段落,等以后有了更多的积累,我会继续写下去。微服务是一个很大的话题,自Martin Fowler于2014年3月提出以来,愈演愈热,并跟另一个话题容器化一起开创了一个全新的DevOps时代,引领了国内外大大小小各个互联网公司的技术走向,也影响了我们这一代程序员尤其是后端和运维的思维方式。从这个角度说,我写这个微服务化改造系列文章也是偶然中的必然,希望能给读过这些文章的你带来一些新的启发和思考。如果你对微服务也感兴趣或者有一些心得想跟我交流,请回复【加群】,欢迎扫描二维码打赏。

少年读书如隙中窥月,中年读书如庭中望月,老年读书如台上玩月,皆以阅历之浅深为所得之浅深耳。——张潮 《幽梦影》