我知道OAuth2和OIDC如何使用自定义作用域和令牌内省来保护这样的URL:
/users/me/documents
我可以为该URL提供documents:view
作用域,当从经过身份验证的用户接收令牌时,我可以询问授权服务器该用户是否具有正确的权限。然后我可以使用preferred_username
声明或类似声明来查看/me
实际上是谁
但是,如果我有一个可供多个用户访问的资源,该怎么办?假设用户有文档,但其直接经理可以查看这些文档。作为经理,要检索员工的文档,我需要有一个这样的url:
/users/${userId}/documents
我如何强制执行它,使只有资源所有者和直接经理才能查看此资源?我不希望每个人都知道userId
来访问每个人的文档。我可以将访问权限作为一个整体授予具有manager
角色的所有用户,但这还不够具体。
我知道有一个UMA
扩展,用户可以代表他向其他用户授予对资源的访问权限,但授予权限的不是用户。在这种情况下,系统规定经理可以访问员工的文件。
编写一个提取${userId}
并执行检查的自定义策略有意义吗?或者这根本不应该由授权服务器来完成,而应该由资源服务器来完成?也许用不同的方法来达到相同的目标?
像这样细粒度的授权是通过声明而不是范围来完成的。用户可以查看哪些文档可能存在业务规则,例如:
- 用户可以访问自己的文档
- 管理员可以查看所有文档
- 经理可以查看其管理人员的文档
在访问令牌中,这可能由以下声明表示:
- 用户ID
- 角色
声明通常是这样的特定于域的,首选选项是在代币发行期间将其添加到代币中。在Curity,我们有一些关于这个主题的好资源:
- 宣称最佳实践
索赔和授权
授权服务器发布访问令牌,然后API(资源服务器(验证访问令牌,并使用令牌数据对每个请求应用授权规则(通常是特定于域的(。
声明通常在需要动态行为时使用——它们是从用户标识派生的运行时值,而范围是固定的设计时值。在您的示例中,API可能还需要更改SQL以根据用户标识检索文档。
此主题有更复杂的变体,例如API调用诸如Open Policy Agent之类的系统,因此返回的文档由安全管理员配置的规则确定。不过,该策略仍将涉及使用访问令牌中的声明。
示例代码
如果有帮助的话,下面是我的一些示例代码,它们显示了在实施特定于域的授权规则时的方法类型。通常,您需要筛选集合并检查对单个项目的访问权限。