写点什么

怎样用六步实现一个安全的中心化认证系统?

  • 2020-03-23
  • 本文字数:4485 字

    阅读完需:约 15 分钟

怎样用六步实现一个安全的中心化认证系统?


随着 Shopify 商家规模的不断扩大,他们会在自己的组织中引入多家商店。以前,这需要请员工到每家商店设置他们的账户。不过,这样让员工管理起来就更麻烦,要做的事情变多,因为他们要管理很多账户。


为解决上述问题,我们创建了一项新服务来处理中心化身份验证和用户身份管理事务,服务的名字就叫身份(Identity)。我们在OpenID Connect(OIDC)规范的基础上,在 Shopify 构建一套中心化身份验证服务。


有了这套系统,我们就有了一个解决方案,能允许用户可靠、安全地合并其帐户,从而实现单点登录并从中获益。解决这一问题的团队由产品管理、用户体验、工程和数据科学领域的专家组成,分布在三个城市(渥太华、蒙特利尔和滑铁卢)的团队成员共同协作。

店铺模型

在 Shopify 的构建设计中,属于特定商店(在我们的数据模型中称为 Shop,店铺)的所有数据都会驻留在单个数据库实例中。这里的数据包括产品、订单、客户和用户等核心业务对象。用户模型代表的是有权访问特定商店的管理界面,并具有特定权限的员工。



商店商务对象关系


用户身份验证和配置文件管理属于店铺本身,并且只要你在 Shopify 上的足迹没有走出单个商店,它就一直生效。商家的组织扩展到多个商店后,管理商店用户的人员和这些用户都会面临更多事务。


由于各个店铺间不会共享数据,所以就没有跨商店的单点登录(SSO)功能。换句话说,你必须单独登录每个商店。用户必须针对他们有权访问的每个商店都维护一份个人资料数据、密码和两步身份验证信息。



商店与用户隔离

在身份服务内建立用户账户模型

在我们的身份服务中,建模的用户帐户有两大类型:分别是身份(Identity)帐户和旧(Legacy)帐户。用户可通过 OIDC 访问的服务或应用程序被建模为身份账户中的目的地(Destination)。Shopify 中目的地包括了商店、合作伙伴仪表板或我们的社区讨论论坛等。


旧帐户只能访问一个商店,而身份帐户可以用来访问多个目的地。



旧帐户模型:每个帐户一个目的地。只能进入店铺


我们的设计中,新帐户都会创建为身份帐户,且拥有旧帐户的已有用户可以安全地升级到身份帐户。最大的问题是将多个旧帐户合并在一起。当用户使用同一个电子邮件地址登录多个不同的 Shopify 商店时,我们会将这些帐户合并为一个身份帐户,而不会阻止他们访问所使用的任何商店。



组合帐户模型:每个帐户可以访问多个目的地


要做到一个账户行天下,我们有六步要做。


  1. 将现有用户帐户中的数据同步到中心化身份服务中

  2. 通过 OpenID Connect 使所有身份验证都通过中心化身份服务处理

  3. 提示用户将他们的帐户合并在一起

  4. 提示用户启用双因素认证(2FA)来保护他们的帐户

  5. 创建组合的身份帐户

  6. 避免创建新的旧帐户

一.将数据从现有用户账户中同步到中心化身份服务中

我们会确保所有用户配置文件和安全凭证信息都从他们管理的商店同步到中心化的身份服务中。这意味着每次以下用户事件之一发生时,就会将数据从存储区同步到身份服务上


  • 创建

  • 删除

  • 个人资料数据更新

  • 安全数据更新(密码或 2FA)

二.通过 OpenID Connect(OIDC)使所有身份验证都通过中心化身份服务处理

OpenID Connect 是对OpenID 2.0规范的扩展,并且是用来将认证从商店委托给身份服务的方法。在执行此步骤前,所有密码和 2FA 验证均在核心店铺应用程序运行时内完成。


鉴于 Shopify 对用于核心平台的数据库是按店铺分片的,所以与特定店铺相关的所有数据都在单个数据库实例上可用。


让所有身份验证都通过身份服务处理的一个缺点是,当用户首次登录一个 Shopify 服务时,它要求将用户的浏览器数据发送到身份服务,以执行 OIDC 身份验证请求(AuthRequest),因此初始登录到一个商店时延迟会长一些。

三.提示用户将他们的帐户合并在一起

如果用户的电子邮件地址可以登录多个 Shopify 服务,我们会提示他们将帐户合并到一个身份帐户中。当旧用户登录到一个 Shopify 产品时,我们在验证了他们身份,但将他们发送到目的地之前中断 OIDC 的 AuthRequest 流程,以检查他们是否拥有可以升级的帐户。


用户有两个主要的身份帐户升级途径:自动升级单个旧帐户或合并多个帐户。


当用户的电子邮件地址只有一个关联商店时,就会自动升级一个旧帐户。在这种情况下,我们会将单个帐户转换为身份账户,保留其所有配置文件、密码和 2FA 设置。身份服务中的帐户使用单表继承来建模,该继承具有一个类型属性,用来指定特定记录使用哪些类。


在这种情况下,升级旧帐户时只要更新这个类型属性的值即可。这不需要在 Shopify 系统中的其他任何位置进行其他任何更改,因为该帐户的通用唯一标识符(UUID)是不变的,这是用来在其他系统中标识某个帐户的值。


当用户的同一电子邮件地址对应多个活动帐户(旧账户或身份账户)时,将触发多个帐户的合并操作。我们为这种合并过程创建了一个新的会话对象,称为 MergeSession,用来跟踪创建身份帐户所需的所有数据。MergeSession 与一个单独的 AuthRequest 相关联,这意味着当 AuthRequest 完成时,该会话将不再处于活动状态。如果用户经历了多个合并过程,则我们必须为每个合并过程生成一个新的 MergeSession 对象。



用户拥有多个可以合并的帐户时看到的提示


Shopify 不需要用户在创建新商店时验证他们的电子邮件地址。这意味着有人可能会使用他们无权访问的电子邮件地址来注册试用。因此,我们需要先验证你对电子邮件地址拥有访问权限,然后才能显示与相同电子邮件关联的其他帐户的用户信息,或者允许你对其他帐户执行任何操作。这一验证过程中,你需要请求将带有链接的电子邮件发送到你的地址。


如果用户登录商店使用的电子邮件地址通过了验证,我们将列出使用该电子邮件地址的所有其他目的地。如果用户要登录账户的电子邮件地址未通过验证,那么我们只会指出该地址还关联了其他帐户的事实,并且在继续合并过程之前,用户必须验证自己的电子邮件地址。



用户使用未经验证的电子邮件地址登录时看到的提示


如果需要合并的所有帐户都开启了 2FA,则用户必须为每个要合并的帐户提供一个有效代码。当用户使用 SMS 作为 2FA 方法时,如果他们在多个帐户中使用相同的电话号码,则可能会在此步骤中节省一些时间——因为对于使用相同号码的所有目的地,我们只需要一个代码即可。


对我们的用户来说,这样的便利更安全,目的是要减少在这一步骤上花费的时间。但是,使用身份验证器应用(例如谷歌身份验证、Authy、1Password 等)的用户必须为每个目的地都提供代码,因为身份验证应用是针对各个用户帐户配置的,彼此之间没有任何关联。


如果用户除了自己已经登录的帐户外,无法为其他某个帐户提供 2FA 代码,则可以将这个帐户排除在合并范围之外。某人可能无法提供代码的正当理由包括:该帐户使用了他无法使用的旧 SMS 电话号码,或者他不再拥有配置为该帐户生成代码的身份验证应用。


这里的思想是,将来用户重新获得对某个帐户的访问权限时,可以在那时候再合并之前被排除的帐户。


满足所有帐户的 2FA 要求后,我们会提示用户为其合并帐户设置一个新密码。我们将加密的密码哈希存储在跟踪这个会话状态的对象上。

四.提示用户启用双因素认证(2FA)来保护自己的帐户

让用户参与帐户的维护工作是一个极好的机会,可以借此让他们从双因素帐户保护措施中受益。


我们向已经在至少一个帐户中启用了 2FA 的用户显示的是另一种流程,因为这里的假设是不需要向他们解释什么是 2FA,但是从未设置过 2FA 的用户很有可能需要这种解释。

五.创建组合身份帐户

一旦用户确认了自己选择的 2FA 配置,或选择不对其进行设置,我们将执行以下操作:


将 2FA 设置(如果存在)附加到跟踪特定帐户组合会话(MergeSession)的对象。



合并具有新密码和 2FA 配置的会话对象


在单个数据库事务中,创建一个完整的新帐户,将旧帐户中的目的地与该帐户关联,并删除旧帐户。


从用户那里获取所有信息后,我们需要在一个事务内执行这步操作,以免削弱帐户的安全性。如果用户在开始此过程前就在使用 2FA,并且我们在获得新密码后立即创建了身份帐户,则会存在一个很短的时间范围,其中新身份帐户的安全性会低于旧帐户。


身份帐户一旦存在并具有与之关联的密码,就可以在只知道密码的情况下将其用于访问目的地。将帐户创建推迟到密码和 2FA 都定义好之后的话,新帐户就能像合并之前的帐户一样安全。



合并账户的最终状态


为新帐户生成一个会话,并使用它来满足最初发起该会话的 AuthRequest。


此过程中,一些较复杂的逻辑部分包括:查找给定电子邮件地址的所有相关帐户以及他们有权访问的目的地的信息,在创建身份帐户时替换旧帐户,并确保身份帐户设置时所有必要数据都正确定义好。


针对方案中的这些需求,我们依赖一个名为ActiveOperation的 Ruby 库。这是一个非常小的框架,允许你在一个操作类中隔离和建模应用程序中的业务逻辑。传统上,在 Rails 应用程序中,逻辑最后必须放入控制器或模型中;在我们的情况下,我们将复杂的业务逻辑定义为操作,从而获得了非常小的控制器和模型。鉴于这些操作是隔离的,并且每个单独的类都要负责非常具体的职责,因此这些操作很容易测试。


还有其他库可以处理这种业务逻辑流程,但是我们选择 ActiveOperation 的原因是它易于使用,让我们的代码更容易理解,并且对我们使用的RSpec测试框架具有内置支持。


在开始向用户推出帐户合并流程时,我们在身份服务中添加了对新的 Web 身份验证(WebAuthn)标准的支持。这意味着我们能允许用户在保护帐户安全时使用物理安全密钥作为第二个因素,在原有的 SMS 或身份验证应用的基础上又多了一个选择。

六.防止创建新的旧帐户

我们不想再创建任何旧帐户了。使用身份创建流程需要更新两个用户场景:在shopify.com上注册新的试用商店,以及邀请新员工进入现有商店。


注册新商店时,你将在这一过程中输入你的电子邮件地址。该电子邮件地址会被用作新商店的主要所有者。对于旧帐户,即使电子邮件地址属于其他商店,我们仍将为新创建的商店创建新的旧帐户。


邀请新员工到你的商店时,你将输入新用户的电子邮件地址,然后将向该电子邮件地址发送邀请邮件,其中包括接受邀请并完成帐户设置的链接。与商店创建过程类似,这会在每个单独的商店上创建一个新的旧账户。


在这两种情况下,我们都将引入新的流程来确定这个电子邮件地址是否已经属于一个身份帐户;如果是,则要求用户先验证属于该电子邮件地址的帐户,然后才能继续。

总结

截至本文撰写时,我们超过 75%的活跃用户帐户已自动升级或合并到一个身份帐户中了。不需要用户交互的帐户(例如可以自动升级的帐户)可以自动完成升级,而无需用户登录。要求用户证明其帐户所有权的帐户只能在登录时完成合并。将来,我们将阻止用户在没有身份帐户的情况下登录 Shopify。


当 Shopify 的产品团队面对的都是拥有身份帐户的活跃用户时,我们就可以开始为那些将身份验证和配置文件管理委派给身份服务的用户建立新体验。验证过程还是要由利用这些身份账户的服务来处理,因为身份服务专门是用来处理身份验证的,而对有关帐户可以访问的服务权限一无所知。


对我们的用户来说,这意味着当 Shopify 启动使用身份服务处理用户登录的新服务时,他们就不必再创建和管理新帐户了。


英文原文:


How to Implement a Secure Central Authentication Service in Six Steps


2020-03-23 18:082601
用户头像
王强 技术是文明进步的力量

发布了 786 篇内容, 共 377.5 次阅读, 收获喜欢 1715 次。

关注

评论

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

Nacos 配置中心源码 | 京东物流技术团队

京东科技开发者

源码 nacos 源码剖析 配置中心

Sermant:无代理服务网格架构解析及无门槛玩转插件开发

华为云开发者联盟

云原生 后端 华为云 华为云开发者联盟 DTSE Tech Talk

零基础也能搞定文案生成应用,半小时包教包会!「大模型摇摇乐」硬核教程来啦!

飞桨PaddlePaddle

人工智能 代码 零基础 开发教程 文案生成

【数据安全】金融行业数据安全保障措施汇总

行云管家

金融 数据安全 运维安全 数据安全运维

010 Editor 十六进制编辑器 注册激活版 mac/win

Rose

010 Editor下载 010 Editor破解版 010 Editor注册码 16进制编辑器

如何将在线教育小程序一键生成App

Geek_2305a8

VisualDiffer for Mac(文件夹和文件比较工具) 1.8.9中文激活密钥版

mac

苹果mac Windows软件 VisualDiffer 文件快速比较工具

SVN管理工具Cornerstone for Mac入门教程 Cornerstone永久破解资源

Rose

NFTScan | 12.04~12.10 NFT 市场热点汇总

NFT Research

NFT NFTScan nft工具

Amazon CodeWhisperer 免费的 AI 代码生成助手!最新体验反馈~

亚马逊云科技 (Amazon Web Services)

人工智能 亚马逊云科技 云上探索实验室 Amazon CodeWhisperer

LED透明屏市场前景展望

Dylan

全球经济下行 中美贸易 LED LED显示屏 led显示屏厂家

SVN优缺点详解及版本控制系统选型建议

龙智—DevSecOps解决方案

svn 版本控制

oracle dblink mysql查询text无法显示问题

百度搜索:蓝易云

MySQL oracle Linux text DBLINK

Web网页端IM产品RainbowChat-Web的v6.0版已发布

JackJiang

网络编程 即时通讯 IM

万界星空科技低代码平台:搭建MES系统的优势

万界星空科技

低代码 数字化 MES系统 低代码开发 mes

docker通过dockerfile安装sftp教程。

百度搜索:蓝易云

Linux 运维 Dockerfile 云服务器 sftp

Q-learning 入门:以 Frozen Lake 游戏环境为例

Baihai IDP

人工智能 程序员 AI 强化学习 白海科技

Topaz Video AI for mac v4.0.7注册激活版 人工智能视频增强 支持M/Intel

Rose

mac软件下载 人工智能视频增强 Video Enhance AI 下载 Video Enhance AI 注册

mac强大的音频处理工具Ableton Live 12 中文版最新

胖墩儿不胖y

Mac软件 mac音频编辑器

Atlassian发布四个CVSS风险评分9.0或更高漏洞,影响多个产品

龙智—DevSecOps解决方案

Atlassian

Wireshark中的http协议包分析

小齐写代码

Fusion Studio 18 v18.6.4完美兼容破解版 附Fusion Studio激活补丁

Rose

mac视频后期特效处理 Fusion Studio 18下载 Fusion Studio激活秘钥 Blackmagic Fusion Studio

基于FFmpeg实现一个数据流风格的视频处理工具 | 社区征文

为自己带盐

ffmpeg #技术人的2023总结

SmartGit for Mac(老牌Git客户端)v23.1.1中文注册版 支持M/intel

Rose

SmartGit破解版 SmartGit许可证 Git 客户端 SmartGit for Mac SmartGit 中文

视频后期特效合成软件:Blackmagic Fusion Studio18 激活最新

mac大玩家j

Mac软件 特效合成工具 Mac软件特效

MongoDB和阿里云携手驱动WeLab 引领超千万用户迈向智能金融未来

Geek_2d6073

CloudQuery x 达梦,国产数据库正当时

BinTools图尔兹

数据库 数据库管理 数据库安全 达梦 兼容适配

大模型发展的前景与挑战 主赛道:技术人的 2023 总结

不叫猫先生

大模型 ChatGPT #技术人的2023总结

INTO领航:2023社交变革峰会揭示数字社交的未来格局

Geek_2d6073

开源MES/免费MES/开源MES生产流程管理

万界星空科技

开源 开源代码 开源软件 免费开源 开源mes

软件测试/人工智能丨成员运算符

测试人

人工智能 软件测试

怎样用六步实现一个安全的中心化认证系统?_安全_Justin Filip_InfoQ精选文章