Authing 身份云的云原生探索与实践|干货

7月17日,「ECUG Meetup 第 2 期」活动中,Authing CTO 尚斯年带来了以《Authing 身份云的云原生探索与实践》为主题的大量干货分享,本文是对分享内容的整理。

本文长达 7000 余字,以下为正文:

01 Authing 就是身份云

很多人不知道 Authing 是什么,这里我用一句话概括:Authing 就是“身份云”,我们希望将身份做成一种基础设施放到云平台上。

我们为什么做这件事情?是因为发现互联网发展过程中有个脉络。

2000 年初网易、新浪、搜狐等平台的兴起出现了“内容在线”;接着出现了“沟通在线”,例如微信、QQ;之后出现了“娱乐在线”,再往后就是“交易在线”,比如电商、京东。

互联网发展到现在,办公场景逐渐在线化。钉钉、企业微信等产品已经融入到我们日常办公生活中——人的身份可以贯穿互联网的生活。

软件发展初期,身份是其很重要的一部分,比如你买了 SAP,需要注册帐号才能正常使用,但是不同应用的帐号体系但是相互之间是割裂的;软件发展至今,身份识别已经变成了独立的平台,例如 Google、Microsoft、Office365、Facebook 帐号等,其中 Facebook 的用户可以通过帐号登录多个不同的业务系统或者平台,实现这一切都是基于 OpenID 的身份互通的协议。

未来必须要有个统一的或者中心化的平台来解决所有身份问题,这同样也是我们的愿景。Authing 作为一个通用平台,既能支持云应用、IoT 应用;也能支持设备、私有云平台以及不同的组织;不仅如此,我们还能支持统一的面向私有云、公有云、混合云身份解决方案。

软件发展初期,“身份是软件一部分”的方案由于成本和复杂性的限制。如今,我们使用Facebook 的社交账户去登录其他平台。未来我们希望看到通过 Authing 这种统一的身份平台去连接任何组织和任何应用。

设计初期,从最简单的登录框开始分析,我们发现现存的应用登录框的设计其实非常简单,有用户名、密码即可登录,但这种方式存在以下问题:

  1. 不同系统需要重复登录;
  2. 需要记住大量帐户和密码,不同的应用系统之间的帐号体系不通用的;
  3. 登录方式单一,基本是用户名、密码或者手机验证码,且不支持较先进的登录方式,比如人脸、指纹、生物识别;
  4. 安全保障机制单一,通过密码对人的身份校验;
  5. 没有用户自助服务,仅支持管理员统一管理;
  6. 用户自身关联性较少;
  7. 缺乏自定义界面;
  8. 用户补全信息功能无法使用。
    我们的目标是满足以前用户需要但没有实现的需求:
  9. 可以切换显示语言;
  10. 当用户遇到问题时可以随时向平台反馈;
  11. 支持不同的登录方式,也支持普通登录、扫码登录等等。

下图是 Authing 平台的登录框页面:

登录框虽然只是我们做这件事的冰山一角,但在冰山之下却暗含很多能力,包括认证、授权和用户目录管理等等。企业在做内部组织管理的时候也面临诸多挑战:

  1. 通过企业微信、钉钉这种单点登录方式的系统,此业务系统是与三方的 SaaS 软件集成的;
  2. 面向 CRM 销售的业务系统,它的组织是面向单独财资组织,跟企业的主组织并不一样;
  3. 跨国公司,集团公司和分公司的组织结构,这种场景下的组织融合问题是很有挑战的;
  4. 用户管理和访问策略。

我们了解到从事研发的同学都知道 RBAC 访问策略,这是一种相对简单的访问控制。传统的 RBAC 缺乏风控识别能力,所以我们希望 Authing 平台的访问策略能得以改善,在配置权限时不仅能实现基于规则的权限配置,还能实现基于用户行为风控策略。

企业员工在入职时需要找管理员分配员工帐号,如果不同业务系统需要找不同的管理员分配帐号,这样就会让入职流程变得复杂。虽然大家在入职时或许也可以接受这种复杂操作,但员工离职时会出现非常大的安全风险。所以我们针对这一问题设计了一套身份供给和反供给方案,当员工入职之后会自动向下游系统创建账号,当员工离职之后会自动收回账号。

Authing 平台从登录框入手,做一整套围绕身份的服务。

我们从两个角色的角度来分析,一个是用户身份,另一个是员工身份,这两个角色概念是不一样的。用户身份更偏向于面向 ToC 的场景,例如电商、社交;员工身份面向是内部组织管理场景。我们希望 Authing 平台既能为企业内部提升效率,也可以成功帮助企业实现业务增长。我们可以通过提供用户画像来管理用户身份,使得企业可以从用户身份中获取更多信息并实现运营效率的提升。目前 Authing 平台客户有安永、THERAGUN 这样的外企,有中国石油、高等教育出版社这样的国企,最近也做了一些车企项目。

下图是我们的发展历程,我们是非常年轻的公司,2019 年成立,到现在是 2 年时间,去年完成了三轮融资。

02 向云而生,IAM 到 IDaaS

回到我们这次主题,关于云原生我们做了哪些工作?我们的主题是“向云而生,IAM 到 IDaaS”。首先我们先谈IDaaS、IAM的概念和区别。

IAM 是“Identity and Access Management ”的缩写,即“身份识别与访问管理”。IAM 是一套通过全面建立和维护数字身份,并提供有效地、安全地 IT 资源访问的业务流程和管理手段,从而实现组织信息资产统一的身份认证、身份授权和身份数据的集中管理与审计。

通俗地讲:IAM 是让合适的人在恰当的时间通过统一的方式访问授权的信息资产,提供集中式的数字身份管理、认证、授权、审计的平台。

我们为什么还需要 IDaaS?是因为传统的 IAM 有几点不足:

1)运营能力弱,传统 IAM 账号中心的运营能力较弱,难以满足大型组织在业务方面的需求,例如,筛选出六个月内未登录过的用户,并向他们发送营销短信;或找到那些高频使用的用户并交由客户经理转化商机。
2)缺乏伸缩性和扩展性,当企业的用户量不断上升时,用户系统承载的压力也会不断增加,传统的 IAM 主要靠堆积服务器和设置负载均衡来优化,但登录失败的次数总是随着用户量的增长而增长,这对企业和用户来说都是灾难。
3)运维费用高,大多数 IAM 专家难以雇佣并且费用高昂。而且当企业计划将内部员工训练成专家时,他们面临着将训练好的员工流失到咨询公司或竞争对手那边。
4)安全性欠佳,数据资产正在逐渐超越实体资产成为企业最有价值的核心。而针对数据资产的盗窃和攻击也呈不断上升趋势。传统的 IAM 在本地构建,难以保障混合云环境下的企业安全,权限管理颗粒度较粗,访问控制策略单一。
5)难以更新换代,大多数企业的 IAM 系统需要消耗巨大的人力物力去更新换代,而当企业耗尽千辛万苦将系统更新好了之后,市面上又出现了新的技术和系统。

IDaaS 是在 IAM 基础上加上了云计算,相比 IAM 增加很多优势:

1)多种认证与访问控制策略、灵活高效;
2)基于云原生架构、天然适应,海量数据存储;
3)多维度保障数据安全;
4)在 IAM 的基础上实现全面拓展。

所以我们的能力是一种可复用的身份基础设施,是以身份作为基础设施的一种来看待我们这个产品。

从云计算角度看 IDaaS,我们是在哪一层?我们都知道云计算有 IaaS、PaaS 和 SaaS 三层,我们更多是 PaaS 和 SaaS 之上的一层,面向应用和用户侧。近年来联网的设备爆炸性增长,企业级的数据量也在增长,企业所用到的应用也在增长,我们是在这之上提供了统一的组件,它包含登录、注册、身份鉴权、用户交互这些功能,在 PaaS 和 IaaS 之上 SaaS 层提供了云的统一身份管理解决方案。

我们面对客户有不同的交付环境,私有云、混合云、公有云,我们是如何交付我们的产品?在这之上我们提出了“云中立”的概念,我们的产品交付在用户任何云环境上。

比如这个客户只 30 个人,没有必要太复杂架构,在我们平台一个 SQLite 就可以跑起来。如果这个用户是 2000-10000 人的规模,需要一定可靠性、安全性的保障。又或者是私有化方案,我们可以使用开源组建进行替换。我们开发者用户或者中小企业说没有必要私有化部署,直接用公有云平台,我们是在公有云之上提供公有云的解决方案和组件,这些东西都是可以替换的,我们做一套适配层 Adapter,可以在任何云平台上部署我们的产品。我们的产品已经部署在腾讯云、阿里云、AWS、Google 和用户的私有云上。

我们在公有云上也有一套高可用的架构设计,这也是比较经典的一套,就是多 Region 的概念。

我们的平台是架设在 AWS 中国区,在一个 Region 中使用多个可用区,使用负载均衡,跨可用区构建双集群和数据库。当一个可用区出现故障后,我们可以立刻启动另一个可用区。最近我们也有客户采用跨国方案,我们也会在 AWS 数据库上构建 Global Database,各个国家之间就近接入。大致的思路是一样的,去构建多 Region 高可用的技术架构。

Kubernetes 在我们创立这家公司时也成为了一个事实的标准,所以我们在构建时是面向 Kubernetes 的。Kubernetes 除了是本地化部署,也可以是云上部署。小规模的本地化部署比较简单,可以用 Docker Compose 这样的方式,我们在私有云交付的时候可以直接交付一套 Kubernetes 的编排。

在 Kubernetes 之上构建一套多租户方案,很多企业不同的业务系统希望有不同相互隔离的身份平台,比如之前有个金融行业客户,它需要华北区是一套独立的身份平台,分为开发环境、线上环境,如何用统一的配置管理平台解决这些问题?所以我们在 Kubernetes 之上构建了一套多租户方案,我们在基于 Kubernetes 的 API 实现快速创建一组或多组 Authing 服务。

03 面向服务的认证与授权

刚才提到身份时基本提到的是面向人的身份,我们现在聊一下机器间的认证与授权。在微服务架构,尤其云原生倡导微服务时,如何进行服务治理?服务之间是如何完成认证和授权的?有没有统一的方案?

在我们的平台,基于 OpenID 的标准协议实现 M2M 的身份授权解决方案,M2M 是 Machine-to-Machine 的缩写,指的是服务之间的认证与授权。举个简单的例子,如果你是个外包商,需要将业务 API 提供给业务方,几个外包商给客户开发一个大屏的数据展示,你希望将某些非核心的 API 访问授权给外包商,外包商完成非核心部分应用开发需要授权,过程中不需要用户参与,只需要确定来访者是哪些外包商以及哪些接口。

授权就像左图的服务 A 调用服务 B 和服务 C,B 允许服务 A 调用时,有让服务 A 调用服务 B 的权限,C 没有这样的权限。我们发现这种模式有一个问题,就是对代码有侵入性和耦合性,像服务 B 时、服务 C 有个专门认证模块,去判断服务 A 是否能调用,这些与业务无关的认证模块很有必要,我们可以在中间加一个统一的中间件 Authing,所有的认证控制都是通过 Authing。

讲到这里,很多对云原生比较了解的同学就知道我下面要讲了什么,就是 Service Mesh 概念,Service Mesh 是可以天生支持服务间的相互控制,包括流量控制、数据控制,像服务之间的认证与授权。

04 开发者友好的身份云

我们做身份云平台之中非常关注开发者体验,这也是云原生很重要一个概念。

我们产品迭代有个概念叫「API First」,将所有能力 API 化提供给开发者。我们的目标是开发者完全可以基于我们平台的 API 做一个和我们平台一模一样的产品。用户可以通过不同设备访问我们平台全量的 API。

这是面向开发者最大的价值,在 CNCF2020 开发者现状报告中,现在全球有超过 470 万开发者在使用云原生技术,占全部后端开发者的 36%。开发者已经成为云原生变革最主要的推动力量。

我们在平台中提供全量的 SDK 和 API,后端的像 java、Python、.NET,前端的像 JavaScript,安卓、iOS,还有跨端的 React Native、Flutter。希望 API First 的体系架构是一种设计方法,它以 API 为中心,我们认为 API 开发出来的应用就像乐高积木一样模块化,是可复用可扩展的。面向 API 就是面向开发者,可以更好将身份服务集成在开发者和企业的业务当中。

在 API 之上我们提出了 Hyper Component 的概念。经常我们把 API 交付给客户时,客户说用你的 API 要进行二次开发,还要封装组件。我们将登录框做成组件的形式,只需要几行代码就可以嵌入到我们的应用系统平台之上。考虑到前端有不同的框架,我们也面向不同前端框架提供统一的组件化方案,同时支持 React、Angular 和 Vue,完全可以集成在企业和开发者自己的平台之中。

虽然我们提供了 API、提供了组件,用户的诉求是千变万化的。举几个用户常见的想法:
想要获取用户注册来源;
想要在系统维护期间,禁止用户访问登录;
注册之后,希望自动发送钉钉、企业、飞书信息;
希望在白名单的用户才可以访问;
希望收到邀请的用户才可以访问。

用户的诉求无穷无尽,有没有一种方式尽可能满足用户的诉求?
我们还创建了「Authing Pipeline」的概念。Authing Pipeline 是一组运行在云端的用户自定义 JavaScript 代码,可以让开发者扩展、自定义 Authing 能力。在认证身份流之中,登录、注册前后都可以插入钩子执行用户定义的函数。所以身份服务是一种统一平台,面向用户不同场景,去适应用户的场景。

还有一个问题是用户担心数据的安全性,尤其是外企的用户经常说你们的数据是不是被政府所监控?我们核心业务数据放在你这不安全?所以我们提供了自定义数据库的功能,用户的数据完全由用户做主,企业或开发者的数据并不存储在 Authing 上,在每次认证时通过调用脚本访问自身平台的数据,这种方式有一定的性能损耗,但是安全性更好,我们提供了这样一个自定义数据库的连接。

我们有两种数据库连接模式。一种是惰性数据迁移模式,每次用户访问自身数据库,完成信息比对之后将数据惰性迁移到平台;还有一种完全使用你自己的数据库,我们平台只完成用户身份认证,不存储任何数据。这种模式是通过脚本,脚本是 JavaScript,可以连接像 MangoDB、MySQL 数据库等等。

上图是完整的技术方案,在用户完成认证的时候,我们进行函数计算,函数计算也是通过后台上传的,像 AWS 或者阿里云、腾讯的云函数计算,用户通过自身云函数计算访问自身数据库完成数据接入。

这个方式也有问题:

1)构建和上传速度慢、用户体验差;
2)有网络通信时间延迟,登录等待时间长;
3)函数冷启动问题,虽然现在各大平台将函数的冷启动基本解决了,面向温启动,几十毫秒之内能够启动,但是对用户来讲也是没必要的损失;
4)和我们云平台耦合性比较重,私有化部署时无法实现快速接入。

我们找到了 Safeify 的 Javascript 沙箱解决方案,相比之前其他沙箱模式这个方案提供更好的资源隔离能力。这种沙箱可以通过进程池管理调度沙箱进程,处理的数据和结果,还有公开给沙箱的方法,针对沙箱进程进行 CPU 和内存配额限制。它的核心是沙箱运行在不同进程,然后完成任务。

05 Authing 快速发展背后的云原生技术

刚才讲了提供给开发者的各种方式和好处,也讲讲基于云原生技术,我们是如何快速发展的。我们在 2 年内完成快速发展,去年完成第三轮融资,我们平台有千万级的客户,我们是如何做到这些的呢?

第一点,构建基础设施及代码方案。使用 Terraform 编排。业务上云对 IT 基础设施的管理提出了更苛刻的要求,我们需要:
1)更好的系统效能:及时了解相关领域而规避了风险,确保了合规和 IT 基础设施的安全;
2)更快的速度:在今天,软件交付/更新的速度被认为是成功背后最重要的因素之一,需要保证基础设施的高效迭代;
3)高效的变更管理:在部署到生产环境之前,代码常常被修改和测试。基础设施即代码确保了在不同设备、平台和系统中实现更安全和高效的变更管理;
4)可扩展的基础设施:硬件的虚拟化使得在需要时增加、替换和扩展资源。

面对这个问题,我们使用了 Terraform 这个编排。给客户交付时,如果客户希望部署在阿里云平台,也基于 Terraform 进行快速基础设施搭建,当用户有基础设施和环境变更时,可以快速完成底层基础设施的变更,而且每次变更都是有迹可寻的。

第二,持续交付。云原生系统之中应该关注用户交付能力。并没关注以下两点:

1)概念和操作尽可能简单,每一个成员无论技术水平高低,都可以可以快速理解 CICD 流程并将自己代码发布到不同环境。
2)最小适用,如无必要勿需增实体,用尽可能简单的组件完成代码集成和上线交付。发展之是,我们希望所有的东西尽可能简单,一个组件完成交付,就不会扩大更多组件,保证系统的复杂性。

第三,日志与监控。我们是一个 SaaS 平台,保证 7×24 小时高可用,有任何线上问题要及时暴露出来,这张图展示的是我们基于 Prometheus 的监控与报警解决方案。

Q & A

Q:我想问一下单点登陆在一个登陆之后,在其他平台上也能够实现完成登陆的登陆态。它如果实现登陆之后,减少社会化登陆的过程,那登陆好之后如果有一个点下线了,你们是怎么进行通知的?

尚斯年:第一点,单点登陆是我们模块之中一个,但并不是我们全部,还有像用户目录、融合等等。一般登陆通过 token 的方式是没有登陆信息的,登陆之后向业务系统推送消息,让它把自身的给删除掉。

Q:退出登陆之后有没有在线统计或者系统检测?一个点退出之后,另外一个点能不能主动得到消息?还是等下一次有活的时候它自动下线?里面有在线用户时长统计?

尚斯年:不是,我们是直接给它发一个消息,它通过这个退出的消息,比如它在系统 A 退出了,我会给 B、C、D 消息,让它把 B、C、D 退出了。在线用户时长统计是有的,这就是我们增加运营的能力。

Q:如果我们的内部系统接入,但是内部系统还是有些权限的,我们是不是基于你们的平台才能做二次开发?

尚斯年:一些细粒度的权限需要通过 API、SDK 接入的,还有一种方式是在网端这一层,所有的权限校验都在网端,对象后面是透明的使用方式。

Q:你们产品的愿景是说更像一个 ToC 的愿景,但是你们的应用是个 ToB 的应用,这中间是什么关系?

尚斯年:很多厂商是纯做 ToB 的,有很多厂商是纯做 ToC 的。我们是国内首家做 CIM 和 EIM 两种场景,E 就是面向企业的,身份是一种基础设施,拿基础设施用的时候不应该考虑它是 C 和 E,就像你用 Kubernetes、MySQL 时不会考虑 Kubernetes 在 C 的场景还是 E 的场景,我们是两套兼容这两个场景的解决方案。

Q:社区有一些邦联式数据,你们也支持邦联式的?还是全套是你们的?

尚斯年:支持邦联式的,身份联邦也是支持的,可以互相传递身份的认证。