写点什么

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:053636

评论

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

在 ABAP 技术栈里实施 Continuous Integration 的一些挑战

汪子熙

DevOps 持续集成 abap 5月月更 持续优化

11-SpringSecurity:Session共享

爱好编程进阶

Java 程序员 后端开发

高精度在线计时器(秒表)

入门小站

工具

pinpoint插件开发之二:从零开始新建一个插件

程序员欣宸

Java 分布式 4月月更

阿里架构师耗时 176 天整理出来的 Java 独家面试题(10 万字面试总结)

Java架构追梦

程序员 java面试 后端开发

2020年底跳槽面试5家大厂,最后收获拼多多Java岗offer,分享三面总结!

爱好编程进阶

Java 程序员 后端开发

2020面试官会经常问到的三个并发工具类,你都知道吗?

爱好编程进阶

程序员 后端开发

2021最强面试笔记非它莫属:3000字Java面试核心手册(大厂必备

爱好编程进阶

Java 程序员 后端开发

Sentinel集群限流探索

艾小仙

sentinel 分布式限流 集群

linux之秘钥登录

入门小站

Linux

2021最新分享字节四面成功拿Offer!

爱好编程进阶

Java 程序员 后端开发

nginx配置系列(三)日志配置

乌龟哥哥

4月月更

GitOps指南

俞凡

DevOps gitops

2021最新一次Java面试,快手三面一轮游,如今已拿意向书

爱好编程进阶

Java 程序员 后端开发

移动办公安全告急?融云 x 海泰方圆,给即时通讯加把「安全锁」

融云 RongCloud

架构实战营作业四

库尔斯

#架构实战营

C++类设计和实现的十大最佳实践

俞凡

c++ 最佳实践

[Day31-04]-[二叉树]二叉树的堂兄弟节点

方勇(gopher)

LeetCode 数据结构和算法

关于人才的招聘的一些看法(31/100)

hackstoic

团队管理 招聘

网站开发进阶(一)Tomcat域名或IP地址访问配置详解

No Silver Bullet

tomcat 网站建设 5月月更

[Day32]-[二叉树]二叉树中的最大路径和

方勇(gopher)

LeetCode 二叉树 数据结构和算法

Gitea 的简单介绍

HoneyMoose

Java 从一个 List 中删除 null 元素

HoneyMoose

vivo X80系列高端爆款之路:火把照耀在无人区

脑极体

手撕阿里 Spring 框架:AOP、IOC、注解、事务,带你统统拿下

Java架构追梦

Java spring 程序员

架构训练 模块4作业

小马

「架构实战营」

决战摸鱼之巅:将vscode撸成可局域网联机对战的moba平台

gamedilong

前端 vscode nodejs Node 摸鱼

2020最新版Java学习路线图--妈妈再也不用担心我误删数据库被开除了

爱好编程进阶

Java 程序员 后端开发

2021年九月最新Java面试必背八股文,338道最新大厂架构面试题

爱好编程进阶

Java 程序员 后端开发

[Day31-03]-[二叉树] BST树中的众数

方勇(gopher)

LeetCode 数据结构和算法

在线Excel转JSON工具

入门小站

工具

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