身份与权限的论证

1/14/2022 5:50:23 PM
767
0

我们经常看到人们滥用 IdentityServer 作为授权/权限管理系统。这很麻烦——这就是原因。

IdentityServer(因此得名)非常擅长为系统中所有应用程序的用户提供稳定的身份。对于身份,我的意思是不可变的身份(至少在会话的整个生命周期内)——典型的例子是用户 ID(也就是主题 ID)、姓名、部门、​​电子邮件地址、客户 ID 等……

IdentityServer 不太适合让客户端或 API 知道允许该用户做什么——例如创建客户记录、删除表、读取某个文档等……

这并不是 IdentityServer 的固有弱点——但 IdentityServer 是一种令牌服务,而且声明,尤其是令牌并不是传输此类信息的特别好的媒介,这是一个事实。这里有几个原因:

  • 声明应该模拟用户的身份,而不是权限
  • 声明通常是简单的字符串——您通常需要更复杂的东西来模拟授权信息或权限
  • 用户的权限通常会有所不同,具体取决于它使用的客户端或 API——将它们全部放在一个身份或访问令牌中会令人困惑并导致问题。相同的权限甚至可能具有不同的含义,具体取决于使用它的人
  • 权限可以在会话的整个生命周期内更改,但获取新令牌的唯一方法是往返令牌服务。这通常需要一些不可取的 UI 交互
  • 权限和业务逻辑经常重叠——你想在哪里划清界限?
  • 唯一确切知道当前操作的授权要求的一方是它发生的实际代码——令牌服务只能提供粗粒度信息
  • 你想保持你的代币很小。浏览器 URL 长度限制和带宽通常是限制因素
  • 最后但并非最不重要的一点 - 向令牌添加声明很容易。删除一个是非常困难的。你永远不知道是否有人已经严重依赖它。您添加到代币中的每一个声明都应该被仔细审查。

换句话说 - 将权限和授权数据保留在您的令牌之外。一旦您更接近实际需要该信息的资源,就将授权信息添加到您的上下文中。即便如此,使用声明对权限建模也是很诱人的(Microsoft 服务和框架会推动您朝这个方向发展)——请记住,简单的字符串是一种非常有限的数据结构。现代编程语言有比这更好的结构。

角色呢?
这是一个很常见的问题。角色是身份和授权之间的灰色地带。我的经验法则是,如果角色是系统的每个部分都感兴趣的用户身份的基本部分——并且角色成员身份不会或不经常改变——它是令牌声明的候选者。示例可能是Customer vs Employee – 或Patient vs Doctor vs Nurse

角色的所有其他用法——特别是如果角色成员资格因所使用的客户端或 API 不同而不同,则它是纯授权数据,应避免使用。如果您意识到用户的角色数量很高(或正在增长),请避免将它们放入令牌中。

结论
为身份和权限的清晰分离而设计​​(这只是身份验证与授权的重新迭代)。获取尽可能接近需要它的代码的授权数据——只有在那里你才能做出你真正需要的明智决定。

我也经常遇到这样的问题,如果我们有一个类似的灵活的授权解决方案,就像我们使用 IdentityServer 进行身份验证一样——答案是——现在——没有。但我有一种感觉,2017 年将是我们最终解决授权问题的一年。敬请关注!

 

本文来自于  https://leastprivilege.com/2016/12/16/identity-vs-permissions/

全部评论



提问