Shadow mapping¶
在奥斯汀的牛顿峰会上,关于部署者如何使用自动化解决现实世界问题的几个相关问题在松散相关的对话中不断出现
如何将联合用户引导到云端,并赋予他们一定程度的有效授权?
联合用户如何接收角色分配?
无论是否联合,部署者如何为新用户创建“个人项目”? 新用户如何被分配默认项目?
目前,部署者必须通过实施外部编排工具来回答这些问题,这些工具要么预先批量将授权数据填充到 Keystone 中,要么在身份验证过程中进行干预,仅在必要时才这样做。
随着 Mitaka 版本中 shadow 用户功能的引入,Keystone 现在能够持久化本地身份以反映远程用户,从而为本地管理的角色分配打开了大门,而不仅仅是短暂的组 membership。下一步的逻辑步骤是扩展该功能以处理授权难题的其他部分:项目、角色、角色分配和默认项目。
问题描述¶
只有在成功进行身份验证尝试后才会创建 shadow 用户。 因此,联合用户必须尝试进行身份验证,管理员才能直接将其角色分配给其 shadow 身份,从而导致奇怪的用户体验。 诚然,我们有能力提前管理用户组上的授权,但用户组的灵活性不足以涵盖所有人的用例。 例如,我们如何将新用户“映射”到个人项目(特定用户的 tenancy),将“member”角色分配给该用户,并使其成为后续身份验证尝试的默认项目?
提议的变更¶
映射引擎负责将联合属性映射到本地属性。 目前,它基本上能够确定用户名和组 membership。 此更改建议也将用户“映射”到本地项目和角色,以及本地角色分配,这些分配可能存在也可能不存在于身份验证时。
例如,如果在映射中引用了项目名称,则可能需要在分配用户该项目上的“member”角色之前自动创建它。
以下是映射引擎当前支持的内容示例
PUT /OS-FEDERATION/mappings/{mapping_id}
{
"mapping": {
"rules": [
{
"local": [
{
"user": {
"name": "{0}"
}
},
{
"group": {
"id": "0cd5e9"
}
}
],
"remote": [
{
"type": "UserName"
},
{
"type": "orgPersonType",
"not_any_of": [
"Contractor",
"Guest"
]
}
]
}
]
}
}
以下是此规范的结果,映射引擎可能支持的内容示例
PUT /OS-FEDERATION/mappings/{mapping_id}
{
"mapping": {
"rules": [
{
"remote": [
{
"type": "UserName"
},
{
"type": "orgPersonType",
"not_any_of": [
"Contractor",
"Guest"
]
}
],
"local": [
{
"user": {
"name": "{0}"
}
},
{
"projects": [
{
"name": "Development project for {0}",
"roles": [
{
"name": "admin"
}
]
},
{
"name": "Staging",
"roles": [
{
"name": "member"
}
]
},
{
"name": "Production",
"roles": [
{
"name": "observer"
}
]
},
]
}
]
}
]
}
}
上述示例是根据以下考虑构建的
映射显式引用了
domain_id,该 ID 适用于映射模式中的所有对象(用户、项目,甚至可能包括角色)。 这将允许域管理员控制映射,而无需云操作员的干预。 隐含的是domain_id来自身份提供程序,与域之间存在一对一的关系。 Ocata 版本中正在进行的工作是将现有的身份提供程序映射到域。映射引用了多个项目,每个项目都有一组唯一的角色引用。 这意味着用户在各自的项目上拥有这些角色分配。
每个项目名称(和可能 ID)可以根据远程断言动态确定。 如果这些项目中的任何一个不存在,则 Keystone 必须自动创建它们。 由于动态值来自断言,因此可以安全地假设它们只需要创建一次。
用户的
default_project_id属性可以自动设置为列表中出现的第一个项目。 这也可以是稍后添加的内容。 最初,用户的default_project_id不需要设置。项目中的角色应该已经存在。 将新角色添加到部署中的当前工作流程不仅涉及在 Keystone 中创建它们,还可能需要更改部署中各个策略文件(和其他服务)。 在联合身份验证期间动态创建角色可能会导致其他服务没有所需的策略,从而导致不可用的项目。
因此,在此示例中,假设远程 UserName 属性只是“Joe”。 根据映射,如果 Joe 不是访客或合同工,他将
接收一个 shadow 用户身份,用户名是“Joe”,位于 ID 为“ab4e2e”的域中。
接收一个项目范围的“admin”角色,该角色位于自动创建的新项目“为 Joe 开发的项目”中,位于“ab4e2e”域中。
Joe 的
default_project_id将设置为“为 Joe 开发的项目”的 ID。接收直接的用户 + 项目 + 角色分配到三个项目,具有三个不同的角色。
接收一个项目范围的 token(而不是联合用户今天收到的无范围 token),该 token 作用于用户的默认项目。 这反映了本地 Keystone 用户的身份验证行为。
最后,值得一提的是,如果在联合身份验证与 Keystone 之间更改了映射,则新映射的结果将简单地应用,而不会产生任何其他副作用。 映射更改所暗示的授权减少需要通过其他方式处理,因为 Keystone 无法跟踪授权是由于映射还是任何其他方式授予的。 但是,正常的 token 撤销行为仍然适用于由映射创建的角色分配(因此,您可以更改映射,删除由映射创建的项目,并期望为该项目撤销 token)。
备选方案¶
另一种选择是让外部编排工具 要求 Keystone 预测用户身份,并在用户尝试进行身份验证之前预先将 Keystone 填充适当的授权数据。 这做出了一些假设,并对 Keystone 施加了额外的设计约束
操作员假设用户将来某个时候会成功进行身份验证,从而使预填充的授权数据相关且有用。
映射必须定义为操作员查询映射结果时所定义的映射,直到用户最终进行身份验证时。
Shadow 用户 ID 最终必须是可重复的(要么可预测,要么持久),而不仅仅是在身份验证期间懒惰分配的任意 UUID。
我们必须假设操作员愿意(继续)实施此类外部编排工具。 这对于大型部署可能是可以接受的,但对于小型部署来说是一个不切实际的障碍。
安全影响¶
映射引擎已经对 Keystone 的安全模型产生了相对较高的影响,因为它是一个相对复杂且本质上动态的用户身份和授权管理来源。 随着映射引擎扩展以处理授权管理方面的其他功能,这种复杂性只会增加。 部署者应仔细考虑其对映射 API 本身的安全性策略。
我们可能还需要考虑实施额外的约束,以限制映射引擎可以与哪些域交互,可以创建哪些项目,可以分配哪些角色等。
通知影响¶
当用户首次进行身份验证时,这可能会导致大量的通知流量,因为可能会一次分配大量资源。 但是,如果外部工具创建相同的资源,情况也是如此。
其他最终用户影响¶
首次使用的用户将拥有更流畅的体验,通过联合身份验证流程,而无需操作员付出大量的外部努力。
性能影响¶
对于需要分配大量资源给首次使用用户的用户,该调用的性能肯定会受到影响,因为资源将同步创建。 例如,在 Horizon 中,激进的客户端超时可能会导致错误的身份验证失败。
其他部署者影响¶
定义映射规则最终会更加复杂,但权衡是部署者不必在 Keystone 之上管理自定义工具。
开发人员影响¶
无。
实现¶
负责人¶
主要负责人
Ron De Rose (rderose)
Lance Bragstad (lbragstad)
工作项¶
扩展映射引擎的 JSON 模式以支持项目、角色分配和默认项目。
处理映射引擎的额外输出,以创建和分配所需的资源。
使用现有的映射引擎文档彻底记录映射引擎的行为。
依赖项¶
无。
文档影响¶
映射引擎的额外复杂性需要付出大量的努力才能全面记录。
参考资料¶
Keystone 的 工作会话 etherpad 来自奥斯汀的牛顿峰会。
“联合用户体验 + shadow 用户” etherpad 来自奥斯汀的牛顿峰会。
Alexander Makarov 的 联合用户故事 线程在 openstack-dev 邮件列表中。
Adam Young 的 “联合查询 API”规范。