速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

OpenIAM 简介

  • 2019-09-20
  • 本文字数:3117 字

    阅读完需:约 10 分钟

OpenIAM 简介

我们作为链家网的基础架构团队,提供了许多服务给业务线使用。在这个过程中,我们逐渐发现,(业务)服务和(基础)服务之间,“资源隔离”是初期强需求,“权限管理”是远期强需求。

当前,我们有的系统通过客户端传递“用户名/密码”,隐式地将数据隔离在当前用户这个 namespace 下;有的系统使用 AppId 和 AppKey 的方式标明用户,在数据库中更为灵活地记录权限信息。

我们除了作为服务的提供方,还往往需要充当系统管理员的角色:我们通过代码/后台/数据库等方式配置管理权限。这类琐碎的需求隔三岔五出现,可能需要我们线下测试、线上修改,打断了原本的开发节奏;用户可能需要较长时间的等待,压低了预期。

随着提供服务的增多,每个系统都可能需要开发一套用户/资源/权限的子系统,这越来越成为一种负担,拖慢了上层业务的开发,且带来了不一致的用户体验。我们在思考,有没有一个通用服务,覆盖那部分通用性强的,业务无关的权限管理?它只需要很小的成本接入,就能够提供统一的身份识别和方便的权限管理。

实际上,SaaS 平台上早有了成熟的解决方案,它就是 Identity and Access Management 系统。在链家,我们同时使用了自建 IDC 和公有云服务 Amazon Web Service。我们期待自己的服务,也能集成类似 AWS IAM这样的系统。

介绍 AWS IAM

用户体系

在 AWS IAM 中,用户分为四类实体:


  • Account(Root User)

  • 帐号对拥有的资源,有所有权限

  • 帐号可分发权限给用户,或赋予用户权限代为管理

  • 资源隔离在帐户下,不可跨帐号使用

  • User

  • 帐号下的权限隔离

  • 推荐日常使用

  • Group

  • 用户可加入到用户组

  • 方便权限的聚合管理

  • Role

  • 方便第三方跨帐户使用

  • 用户可 AssumeRole 换取临时 AK/SK,切换到对应角色


其中,帐号和用户可以有访问凭证,分别是:


  • 用户名/密码,后台访问

  • AccessKeyId/SecrectAccessKey, 程序使用 HTTP API 访问

认证流程

对于用户请求的身份识别,通常有两种方案:


  1. 基于 Session,Session 过期后重新登录。

  2. 对每次请求加密,一次一密。

  3. AWS IAM 选用了方案二,后端无状态,请求更安全。


用户在程序请求时,使用申请好的 AccessKeyId 和 SecrectAccessKey,针对 Request 的当前时间,Header 字段, URL Query 参数,Body Digest 等元素,按照一定规则拼接字符串,生成签名。


Server 校验签名,确认当前用户,判断是否有对应权限,记录请求以供审计,完成请求返回结果。

策略文档

AWS IAM 使用了 JSON 文档的方式描述策略 Policy,并提供了策略编辑器工具帮助不熟悉的用户撰写文档。


我认为这是很棒的设计:


  • JSON 是程序员们广泛接受,能够手写的格式

  • JSON 支持 Array, Map 等复杂类型,方便聚合权限


官方示例 Policy 如下:


{  "Version": "2012-10-17",      "Statement": [    {    "Effect": "Allow",               "Action": [                      "s3:ListAllMyBuckets",                      "s3:GetBucketLocation"          ],                "Resource": "arn:aws:s3:::*"    },    {     "Effect": "Allow",                 "Action": "s3:ListBucket",                 "Resource": "arn:aws:s3:::BUCKET-NAME",                  "Condition": {"StringLike": {"s3:prefix": [                        "",                        "home/",                        "home/${aws:username}/"          ]}}    },    {      "Effect": "Allow",                 "Action": "s3:*",                 "Resource": [                       "arn:aws:s3:::BUCKET-NAME/home/${aws:username}",               "arn:aws:s3:::BUCKET-NAME/home/${aws:username}/*"      ]    }  ]}
复制代码


Policy 基于字符串的匹配,加上 Allow/Deny Effect 的组合,更通用、易理解的变量名称,和外部系统深度集成的 Condition 条件语句,灵活强大,自成体系。


最终,Policy 通过内嵌(Inline Policy)或附加(Managed Policy)的方式,挂接到帐户里的用户、用户组和/或角色,完成了权限的分发。


整个解决方案,用户使用简洁灵活,可以从策略文档,挂接方式,用户类型上管控;服务提供方只需要暴露出全局性的 Resource 和梳理提供的 Action 即可。用户通过一套机制,完成了对 AWS 所有服务的对接,在 IAM 后台完成了绝大部分权限管理的工作(比如,S3 除了支持 IAM 基于访问用户的权限,还提供了基于对象的管理)

自研

AWS IAM 是个私有服务,我们只能感知客户端 SDK 和后台 Console 的行为动作,S3/EC2 之类的服务和 IAM 之间交互是透明的,无法感知的。我们翻出了私有云的实现 - OpenStack KeyStone,看看是否不用重复造轮子。


在调研阶段,我们发现,KeyStone 只是一个 Identity 服务,只实现了身份的识别,权限信息仍保留在各自的 Service 上。并且,KeyStone 是基于 Role 的设计,即便是一个细微的权限问题,我们也要先建一个 Role 与之对应,然后绑定用户,异常笨重。由于从一开始就存在较大的阻抗匹配,我们放弃了基于 KeyStone 的二次开发方案,使用 Golang 从头开发了自己的实现:OpenIAM。


在决定自研后,我们投入了两个人力(其中一个是没有写过 Golang,帅帅的大三实习生,彬彬同学),在一个多月的时间内,完成了一期目标,完全兼容了 AWS CLI,用 Vue.js 复刻了 AWS 的 Admin Console。


我们除了提供 JSON/XML 的 HTTP 接口供用户日常管理之外,还提供了高性能的 gRPC 接口供服务提供方接入。


我们设定,服务提供方不应知道 SecrectAccessKey 和 Policy 信息。它接到业务请求,只需抽取 AccessKeyId、签名和签名所用字符串,申明签名方式(如 HMac 哈希,Base64 摘要等),再加上服务自身感知到的 Resource 和 Action,一起交由 OpenIAM 完成认证和鉴权两步操作。我们使用这种方式,打通了业务/服务/OpenIAM 三者之间的闭环。


整体的流程如下图:



OpenIAM 在授权认证时的简化活动图:



那么,在 OpenIAM 服务上线后,我们预期会带来哪些改变呢?


  • 服务提供方仅需告知 OpenIAM 创建资源的帐号;后期鉴权均由 OpenIAM 完成,对提供方透明。

  • 资源的拥有者,直接在 OpenIAM 上管理权限;服务提供方无权管理。

  • 客户端逐步统一访问方式,降低接入成本,一套 AccessKeyId/ScrectAccessKey 即可跨多服务使用。

  • OpenIAM 可整合接入服务的服务后台,提供一致的使用体验。

使用场景

我们可以看到,IAM 解决的是服务和服务间的身份认证/权限管理。


在 AWS 里面所有服务都是基础服务,均有较强的资源概念。在公司里,存在更多的业务系统,没有清晰的资源概念,OpenIAM 能够适配这种情况吗?


例如,一个 Restful 的 API 接口,提供了对业务实体的 CRUD 操作。我们可以将每一个业务实体当成一个资源,将 GET/POST/PUT/DELETE 映射成 Action;服务提供方在 Resource 定位符中,直接告知 OpenIAM 资源的拥有者,OpenIAM 即可在此帐号下完成对业务实体的权限认证。


问题二,服务有自己的用户权限体系,用户请求可能涉及到第三方服务的权限问题。用户权限跟 IAM 权限有什么关系,该如何划分边界?事实上,OpenIAM 不关注用户权限信息。业务系统可以有如下两种选择:


1.一般情况下,业务系统的 AK/SK 拥有对第三方服务所需的所有权限,普通用户的权限由业务系统自行判定。


2.业务系统可以预设几个 IAM 子用户,将应用级别的用户映射到不同的 IAM 用户,不同 IAM 用户拥护不同的第三方服务权限。用户请求时,将请求转用对应的 AK/SK 加密,由 OpenIAM 决策允许或拒绝。

总结

在微服务日益火爆的今天,服务的数量会积极膨胀。OpenIAM 希望能解决服务和服务间的资源隔离问题。我们期待能跟大家更深入地分享 OpenIAM 设计与实现,如果感兴趣请留言


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


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


2019-09-20 17:053364

评论

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

Databricks Data Science&Engineering模块介绍

Jackchang234987

大数据 数据产品经理 数据产品 大数据开发 Databricks

Spring Security 在 Servlet 的作用区域

HoneyMoose

Python之斐波那契数列的实现

梦笔生花

Python 9月月更 斐波那契数列

Python之鸡兔同笼

梦笔生花

9月月更 Python语法 鸡兔同笼

开发者有话说|我想给你讲一个故事

石云升

个人成长 9月月更

《MySQL入门很轻松》第4章:数据表中存放的数据类型

乌龟哥哥

9月月更

《MySQL入门很轻松》第5章:数据完整性及其分类

乌龟哥哥

9月月更

从单机百万tpmc到分布式千万tpmc,GaussDB性能提升的3个关键技术剖析

乌龟哥哥

9月月更

字符串哈希

留白的艺术

OptaPlanner场景和示例

积木思维

《MySQL入门很轻松》第2章:MySQL管理工具介绍

乌龟哥哥

9月月更

无线网络安全技术中的王牌标准:WPA到底是个什么东东?解决了什么问题?

wljslmz

网络安全 无线技术 9月月更 WAP

leetcode 513. Find Bottom Left Tree Value 找树左下角的值 (简单)

okokabcd

LeetCode 数据结构与算法

Java中的悲观锁和乐观锁是什么意思?其分类依据是啥?

wljslmz

Java 乐观锁 悲观锁 9月月更

Python之简易计算器的制作

梦笔生花

Python 9月月更 简易计算器

2022-09-30:以下go语言代码输出什么?A: true true false true false; B: true false false true false; C: true true

福大大架构师每日一题

面试官问我 JS 中 foreach 能不能跳出循环

茶无味的一天

JavaScript js foreach for

第56届世乒赛团体赛开幕!三思近900㎡ LED显示点燃赛事激情

电子信息发烧客

微信架构图

Johnny

#架构实战营

(WebFlux)004、WebFilter踩坑记录

编号94530

Spring Boot WebFlux Reactor3 WebFilter

第1章:初识数据库与MySQL----数据库基本概念

乌龟哥哥

9月月更

极速体验SpringCloud Gateway

程序员欣宸

Java SpringCloud SpringCloud Gateway 9月月更

打破线上社交“不可能三角”,语音社交可以做到既要、又要、还要

擎声科技

音视频 sdk 语音社交 实时互动 擎声Qtt

新品速递|海泰边缘安全网关护航工控数据采集

电子信息发烧客

工业4.0时代IIoT存储面临哪些挑战

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

「产品运营」研发效能之DevOps平台如何运营?

laofo

DevOps cicd 研发效能 持续交付 工程效率

14个你必须要知道的ubuntu快捷键

乌龟哥哥

9月月更

给你一本武林秘籍,和KeeWiDB一起登顶高性能

腾讯云数据库

redis 腾讯云 NoSQL 数据库 腾讯云数据库 KeeWiDB

大数据开发应用场景解读

Jackchang234987

大数据 数据开发

数据价值平台化输出:数据服务平台

Taylor

数据中台 接口管理 API接口管理 数据服务 数据服务平台

部署华为云DWS过程

乌龟哥哥

9月月更

OpenIAM 简介_文化 & 方法_尹吉峰_InfoQ精选文章