【AICon 全球人工智能与大模型开发与应用大会】改变 AI 时代下写代码的模式 >>> 了解详情
写点什么

微服务下的身份认证和令牌管理

  • 2021-08-10
  • 本文字数:3968 字

    阅读完需:约 13 分钟

微服务下的身份认证和令牌管理

分布式和微服务架构已经越来越多的应用在企业中,服务间的身份认证和令牌管理是其必不可少的部分。我们的团队在构建一站式门户站点时,需要集成多个后端微服务,每一个服务需要访问不同的系统来完成对应的业务场景 (比如:订单系统,偏好推荐系统,产品系统等)。我们需要将这些系统有机的进行整合,通过在项目中的不断实践,配置恰当的身份认证和令牌管理,我们总结了一些微服务间的身份认证、令牌管理的架构演进与最佳实践。

背景

我们的系统是使用微服务架构开发并打包到容器中,这些系统部署在 Kubernetes(它是用于自动化部署,扩展和管理容器化应用程序的开源系统。它将组成应用程序的容器分组为逻辑单元,以便于管理和发现)。在这些站点中,前端系统需要携带令牌访问不同服务,每一个服务需要携带令牌访问不同的下游服务来完成相应的业务场景,所以这个过程涉及到各个服务之间的身份认证和令牌管理。系统架构涉及到多个微服务,这些微服务系统由不同的团队维护,我们引进了不同的方案来解除各个系统在鉴权上的耦合,降低系统的复杂性,提高鉴权的可复用性和可维护性。本文我们将结合项目中引进的系统自身鉴权,API 网关鉴权和 authentication sidecar 模式,介绍整个上下游服务之间的身份认证、令牌管理的架构演进与最佳实践。

系统自身鉴权

系统自身鉴权,就是每个应用系统自己进行身份认证和令牌管理,下面我们就从 Inbound Authentication 和 Outbound Authentication 来分析。Inbound Authentication



上图是入站身份验证流程,服务消费者调用 Service 时,Service 作为服务提供者需要对消费者的令牌进行验证。具体流程如下:

  1. 服务消费者从 OAuth 服务器获取令牌

  2. 服务消费者携带令牌调用 Service

  3. API 请求流入 Service 中

  4. Service 从 OAuth 服务器获取公钥,验证令牌是否有效。公钥用于验证令牌数字签名。如果令牌有效,则在 Service 中进行业务处理

Outbound Authentication


这是本地的出站请求流程,Service 作为服务消费者携带令牌访问其他后端服务。具体流程如下:

  1. Service 通过 client id 和 client secret 调用 OAuth 服务器获得令牌

  2. Service 携带令牌请求后端微服务

问题和挑战

从耦合性,复杂性,可复用性,可维护性四个维度来看,现在的 inbound 和 outbound authentication 流程面临如下问题:

  • 耦合性:Service 高度依赖于 authentication SDK。从 Inbound authentication 和 OutBound authentication 的流程中可以看到,每一个 Service 都依赖基于自己编程语言的 authentication SDK 验证和获取 token

  • 复杂性:Service 还需要在自己的应用中关注服务间的身份认证和令牌的获取,增加了 Service 代码的复杂性

  • 可复用性:微服务中会有很多业务 domain 和对应不同编程语言的 Service,每个 Service 都需要实现相同的认证流程,这个 authentication 不可以复用

  • 可维护性:如果 OAuth 协议需要升级,如企业要从 Open ID Connect 升级到 Auth0,那么每个 Service 都需要更改自己领域服务的代码

如何来解决这些问题呢,API Gateway 是选项。

API 网关鉴权

什么是 API 网关

API 网关位于客户端与各个微服务间,充当了反向代理的角色,将客户端请求路由到相应的微服务。与此同时,它可以完成安全,限流,缓存,日志,监控,重试,熔断等功能。API 网关方式的核心要点是,所有的接入方和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。身份认证作为 API 网关中的一个组件,可以以模块的方式运行,也可以用微服务的方式运行。

Inbound Authentication



如上图所示,当服务消费者需要请求服务提供者时,

  1. 服务消费者请求 OAuth 服务器获得访问服务端的令牌

  2. 服务消费者携带令牌调用服务端,该 API 请求会先经过 API 网关

  3. API 网关的身份认证服务获取公钥对令牌进行验证

  4. 如果令牌有效,那么请求将流向相关的服务提供者


相比于微服务系统自身鉴权,API 网关鉴权可以来进行 Inbound Authentication,从耦合性,复杂性,可复用性,可维护性四个维度来看比系统自身鉴权都有所改善。

  • 耦合性:Service Provider 不需要高度依赖于 authentication SDK 进行身份认证,而是把其交给了 API 网关

  • 复杂性:Service Provider 不需要在自己的应用中关注服务间的身份认证

  • 可复用性:所有的接入方和消费端都通过统一的网关接入 Service,对于在 API 网关后面的 Service 来说,inbound authentication 实现了复用

  • 可维护性:如果 OAuth 协议需要升级,只需要更改 API 网关里面的鉴权服务的代码

问题和挑战

API 网关没有处理 Outbound Authentication,服务提供者还是需要在自己服务端获取令牌来访问其他服务,所以令牌管理的耦合性,复杂性,可复用性,可维护性问题没有解决。另外如果 API 网关和服务提供者是通过网络通信,那么根据“零信任网络,永远不要信任网络并始终进行验证”原则,我们还是需要在 API 网关和服务提供者实施安全控制,增加了鉴权的复杂性。针对这些问题,Thoughtworks 技术雷达里面收录了一种处于试验阶段的方案 sidecars-for-endpoint-security,后面我们就叫它 authentication sidecar pattern。

Authentication Sidecar Pattern

什么是 Sidecar Pattern

Sidecar 模式是一种解耦的模式,比较适合系统运行在日益复杂的多云或混合云环境中,其中包含多个分布式组件和服务。如这些组件和服务是使用微服务架构开发并打包到容器中,部署在 Kubernetes,Kubernetes 将组成应用程序的容器分组为逻辑单元,以便于管理和发现。



如上图所示,sidecar 附加到 Service 并为 Service 提供支持功能。Sidecar 位于与 Service 相同的 Kubernetes Pod 中,并与 Service 共享相同的生命周期,与 Service 一起创建和淘汰。Ingress sidecar 用于处理到附加到 Service 的入站请求。Egress sidecar 用于处理 Service 到下游 Service 的出站请求。下面会通过对比系统自身鉴权和 authentication sidecar 模式,来对 authentication sidecar 进行分析。

Inbound Authentication Sidecar


上半部分的图是系统自身鉴权的入站身份认证流程,首先服务消费者从 OAuth 服务器获取令牌,然后携带令牌调用 Service, Service 验证令牌。下半部分的图是 authentication sidecar 的身份认证。基础设施级别: Kubernetes 的 Pod 有一个 ingress sidecar 负责验证入站的令牌,authentication SDK 从 Service 分离并放入 ingress sidecar。整体的流程:

  1. Ingress sidecar 启动时从 OAuth 服务器中获取公钥或者证书,服务消费者请求 OAuth 服务器获得访问后端 Service 的令牌

  2. 服务消费者携带令牌调用 Service

  3. 服务消费者的请求会通过 Secure API 会流入到 ingress sidecar 来验证令牌。如果令牌验证失败,则 sidecar 拒绝该请求

  4. 如果令牌有效,那么请求将流向 Service


此外,Service 中还有一个用于运行状况检查的 Health check API。我们可以看到 ingress sidecar 的特性:

  1. Service 中不需要 authentication SDK 了

  2. Sidecar 启动时首先获取公钥并缓存起来,sidecar 可以基于本地缓存的公钥对令牌进行验证,而不是通过网络访问 OAuth 服务器进行验证

Outbound Authentication Sidecar



左半部分是系统自身鉴权系统出站请求流程,首先 Service 从 OAuth 服务器获取令牌,然后携带令牌调用其他后端微服务。右半部分是 authentication sidecar 的 authentication token 的管理。基础设施级别: Kubernetes 的 Pod 有一个 egress sidecar 负责获取出站令牌,authentication SDK 从 Service 分离并放入 egress sidecar。整体的流程:

  1. Service 的请求先流向 egress sidecar

  2. 如果 egress sidecar 缓存中没有令牌,则 sidecar 获取令牌并将其缓存起来。当 token 过期时,它支持自动刷新 token

  3. 如果 sidecar 缓存中有令牌,则不需要请求 OAuth 服务器。然后将 API 请求携带令牌路由到其他后端微服务


我们可以看到 egress sidecar 的特性:

  1. Service 中的 authentication SDK 是不需要的

  2. 当 Service 调用下游时,egress sidecar 会向 API 请求头添加令牌。因为令牌存储在 sidecar 缓存中,不需要每次都调用 OAuth 服务器。当令牌过期时,自动刷新令牌。

Authentication sidecar 的全景图


上面是整个请求的全景图,上游可以是前端或后端服务消费者,Service 是自己团队的应用程序,下游是服务提供者。Ingress 和 egress sidecar 有独立的容器,和 service 容器一样都位于同一个 Pod。

Authentication Sidecar 的好处



上图是系统自身鉴权到 authentication sidecar 的架构演进, 从耦合性,复杂性,重复实现,可维护性四个维度来看:

  1. 耦合性:解除了业务系统和 authentication 的耦合,消除了应用 Service 中的关于身份认证和 authentication token 管理的重复实现,每个业务 Service 无需实现相同的身份验证流程,只需在 kurbernets 的配置文件中对其进行配置。

  2. 复杂性:降低应用系统的复杂性,它将 authentication 委派给与业务系统部署在同一 Pod 中的进程外 sidecar,这样自己的业务系统可以更专注于自身的业务。

  3. 可复用性:身份认证和 token 管理标准化,与编程语言无关。每个 Service 不需要实现相同的认证流程。企业内的团队都可以轻松复用该 sidecar 来进行身份认证和 token 的管理。

  4. 可维护性:只有一个 code base,使得该 authentication sidecar 可以成为企业内部的开源项目,易于进行 OAuth 服务的升级和替换,升级替换时只需要在 authentication sidecar 的 code base 进行改动就可以了。

总结

本文分析了微服务间身份认证和令牌管理的系统自身鉴权,API 网关鉴权和 authentication sidecar 的方案,痛点和好处。软件工程中不可能有任何“银弹” 解决软件的复杂度问题,这几种方案都有相关的条件和限制,下表是关于这三种方案的适用场景。


方案适用场景  
系统自身鉴权单体应用或各系统间没有太多服务通讯;需要快速完成的系统 
API网关鉴权所有的客户端和消费端都通过统一的网关接入微服务,只能进行Inbound Authentication 
Authentication sidecar企业内有很多分布式微服务并有容器化的部署;Service Mesh架构 


针对现在分布式,微服务,容器化架构的流行,许多系统运行在日益复杂的多云或混合云环境中,其中包含多个分布式组件和服务。通过引入 authentication sidecar,使得各自团队负责的 Service 代码更加简洁,解除了业务 Service 和 authentication 服务的耦合,在每一个的 Service 中消除了重复的 authentication 代码,有利于分布式和微服务系统的快速构建,开启了分布式和微服务架构的新体验。


本文转载自:ThoughtWorks 洞见(ID:TW-Insights)

原文链接:微服务下的身份认证和令牌管理

2021-08-10 07:003411

评论

发布
暂无评论
发现更多内容

一文搞定架构思维,DFD 的结构化分析,只需明白这3点

老崔说架构

10种有用的Linux Bash_Completion 命令示例

华为云开发者联盟

Linux 后端 开发

开源的价值观与文化的传递

开源社

#开源

泄露了,Alibaba697页的MySQL应用实战与性能调优手册,太强了

Java编程日记

Java 编程 程序员 面试 架构师

Node 之父着急宣布Deno 将迎来重大变革,疑为针对最近大火的“Bun”

雨果

node.js

为Bert注入知识的力量 Baidu-ERNIE & THU-ERNIE & KBert

了不起的程序猿

Java 编程 后端 java程序员 BERT

国产系统的不足或许可以靠小程序弥补

Geek_99967b

小程序

秒验丨Android端SDK API使用说明

MobTech袤博科技

android UI 秒验

如何在企业数字化团队内部实现分析建模过程全要素的可获得与成果可复现

ModelWhale

团队协作 数字化转型 全要素场景 代码复现 金融场景

乔布斯之后,下一代触控交互由一家中国公司重新定义

硬科技星球

融会贯通,并行不悖 | 2022年8月《中国数据库行业分析报告》精彩抢先看

墨天轮

数据库 greenplum MPP 国产数据库 HTAP

我和谷歌共成长——我的Google Play上车之路

云村的泊

8月月更

华为云构建云原生DevSecOps平台,保障软件供应链全流程安全可信

华为云开发者联盟

云计算 云原生 安全 后端 华为云

【限时领奖】消息队列 MNS 训练营重磅来袭,边学习充电,边领充电宝~

阿里巴巴中间件

阿里云 云原生 消息队列 课程 MNS

从入门到高手,数据从业者成长一般经过哪些阶段?

雨果

数据工程师必备技能

Linux 6.0 第一个候选版本发布

雨果

Liunx

TiFlash 源码阅读(六)DeltaTree Index 的设计和实现分析

PingCAP

TiDB TiDB 源码解读

OpenHarmony轻量设备Hi3861芯片开发板启动流程分析

OpenHarmony开发者

OpenHarmony

微服务、网关、服务发现/注册的正确打开方式

Java全栈架构师

Java 程序员 架构 微服务 程序人生

数据结构——二叉树

工程师日月

8月月更

QCA9882 wallys 802.11AC 802.11AN wifi QCA9882 Module Wireless AC/AN MiniPCIE Standard Card

wallys-wifi6

QCA9882

Solana上的结算协议龙头,Zebec潜力颇受看好

小哈区块

泄露了,22年阿里巴巴秋招内部面试资料,看完之后剑指offer

Java面试那些事儿

Java 编程 程序员 面试 架构师

闲谈Serverless,价值和未来

白留明(Armin.Lionheart)

云计算 Serverless Faas

全新物联网数据集成:Flow可视化编排&双向数据桥接

EMQ映云科技

物联网 IoT flow emqx 8月月更

区块链带你避“坑”,电信诈骗退!退!退!

旺链科技

区块链 产业区块链 电信诈骗

C#/VB.NET 替换 PDF 文件上的现有图像

在下毛毛雨

C# .net PDF 替换图像

QCA9880 wallys 2×2 MIMO 802.11ac Mini PCIe 2,4GHz / 5GHz Designed for E

wallys-wifi6

开源一夏 | 在 STM32L051 上使用 RT-Thread (二、无线温湿度传感器 之 CubeMX配置)

矜辰所致

开源 RT-Thread 8月月更 STM32L051

量化交易合约机器人系统开发策略分析

薇電13242772558

量化策略

4步教你学会使用Linux-Audit工具

华为云开发者联盟

Linux 工具 安全 监控 开发

微服务下的身份认证和令牌管理_架构_张凯峰_InfoQ精选文章