RBAC - 如何实现每个实例的访问控制? (DDD)
RBAC - How to implement per instance access control? (DDD)
在我用 javascript (Node.js) 编写的 DDD 应用程序中,我在授权通用子域的实现上遇到了困难。我检查了 RBAC/ACL 授权模型以了解如何实现它,但它们似乎没有我需要的每个实例权限。
据我了解,RBAC 具有基于角色的授权。用户被分配给角色。角色是分层的并继承权限。角色可以有多个权限。权限允许在资源上执行命令。
但是,根据 RBAC 的定义,资源是通用的,如 "Posts"、"Comment"、"Book" 等。它们不是特定于实例的(如 Post(编号:9283984))。例如,无法在 RBAC 中定义只有创建 Post 的用户才能编辑它。在给定的 "Post(id:2398493)"
上将角色 "Admin" 分配给 "User(id:(8290321)" 似乎是不可能的
定义有权执行修改其他人对特定资源的角色的命令的角色变得更加复杂。
我的申请要求是:
发出CreateLedger
命令的User
被自动指定为这个Ledger
的Admin
。他只能将其他人指定为他 Admin
的分类帐的 Managers
或 Collaborators
或 Viewers
。他也可以撤销这些角色。 Managers
被允许管理 Accounts
的 Ledger
。 Collaborators
可以在此 Ledger
上编辑 Transactions
,而 Viewers
只能查看数据(只读)。 Admin
可以将 Admin
角色分配给他 Admin
的书籍给另一个 User
。
我最初的想法是,为了让用户能够管理用户在资源上的角色,
之间需要有一个映射
user(id:X) -> role(name:Z) -> permissions -> resource(id:Y) -> commands
但在 RBAC 中只能赋值
user(id:X) -> role(name:Z) -> permissions -> resource(name:"Ledger") -> commands
然后,为了克服 RBAC 的这个限制,我想到了用它们的 id 来命名资源,比如
user(id:X) -> role(name:Z) -> permissions -> resource(name:"Ledger:39823847") -> commands
但这似乎是错误的。我还没有看到任何使用资源名称作为实际实例映射的 RBAC 示例。
我用错锤子了吗?我看错了吗?是否有其他一些访问控制模型更适合此任务?或者这是要走的路?如果有人能指出正确的方向,我将不胜感激。
感谢您的帮助
授权为通用子域
如果您想将授权建模为通用子域,那您确实用错了锤子。看看claims-based authorization。使用声明,您可以定义一个声明,如 modify-post:2937472
。或者,您当然可以进一步抽象该信息。
通过这种方法,通用授权子域提供了一个 "container" 其他子域存储关联的位置。因此,这种方法需要仔细整合子域,以便将内容保留在它们所属的位置。
作为支持子域的授权
注意:如果您通过仔细的分析和设计得出授权需要是一个通用的子域,那么以下是不是您想要的。无论如何,我将它添加到我的答案中,因为对于不需要单独授权子域的项目来说,它可能是一个可行的解决方案。所以它来了:
一种根本不同的方法是将授权设计为依赖于核心子域的支持子域。这样,您就可以使用核心模型来定义访问权限,这使得它变得更加简单易懂。
例如,博客系统的授权机制可以使用来自核心域的作者、Post、版主等概念。如果您有复杂的授权要求,这是一个巨大的胜利。
与通用子域方法相比,明显的权衡是授权不是通用的,而是绑定到特定的子域。对于特定项目来说,这可能是可接受的,也可能是不可接受的,但对于不需要单独的、可重复使用的授权机制的小型系统来说,这是一种务实的方法。
在我用 javascript (Node.js) 编写的 DDD 应用程序中,我在授权通用子域的实现上遇到了困难。我检查了 RBAC/ACL 授权模型以了解如何实现它,但它们似乎没有我需要的每个实例权限。
据我了解,RBAC 具有基于角色的授权。用户被分配给角色。角色是分层的并继承权限。角色可以有多个权限。权限允许在资源上执行命令。
但是,根据 RBAC 的定义,资源是通用的,如 "Posts"、"Comment"、"Book" 等。它们不是特定于实例的(如 Post(编号:9283984))。例如,无法在 RBAC 中定义只有创建 Post 的用户才能编辑它。在给定的 "Post(id:2398493)"
上将角色 "Admin" 分配给 "User(id:(8290321)" 似乎是不可能的定义有权执行修改其他人对特定资源的角色的命令的角色变得更加复杂。
我的申请要求是:
发出CreateLedger
命令的User
被自动指定为这个Ledger
的Admin
。他只能将其他人指定为他 Admin
的分类帐的 Managers
或 Collaborators
或 Viewers
。他也可以撤销这些角色。 Managers
被允许管理 Accounts
的 Ledger
。 Collaborators
可以在此 Ledger
上编辑 Transactions
,而 Viewers
只能查看数据(只读)。 Admin
可以将 Admin
角色分配给他 Admin
的书籍给另一个 User
。
我最初的想法是,为了让用户能够管理用户在资源上的角色,
之间需要有一个映射user(id:X) -> role(name:Z) -> permissions -> resource(id:Y) -> commands
但在 RBAC 中只能赋值
user(id:X) -> role(name:Z) -> permissions -> resource(name:"Ledger") -> commands
然后,为了克服 RBAC 的这个限制,我想到了用它们的 id 来命名资源,比如
user(id:X) -> role(name:Z) -> permissions -> resource(name:"Ledger:39823847") -> commands
但这似乎是错误的。我还没有看到任何使用资源名称作为实际实例映射的 RBAC 示例。
我用错锤子了吗?我看错了吗?是否有其他一些访问控制模型更适合此任务?或者这是要走的路?如果有人能指出正确的方向,我将不胜感激。
感谢您的帮助
授权为通用子域
如果您想将授权建模为通用子域,那您确实用错了锤子。看看claims-based authorization。使用声明,您可以定义一个声明,如 modify-post:2937472
。或者,您当然可以进一步抽象该信息。
通过这种方法,通用授权子域提供了一个 "container" 其他子域存储关联的位置。因此,这种方法需要仔细整合子域,以便将内容保留在它们所属的位置。
作为支持子域的授权
注意:如果您通过仔细的分析和设计得出授权需要是一个通用的子域,那么以下是不是您想要的。无论如何,我将它添加到我的答案中,因为对于不需要单独授权子域的项目来说,它可能是一个可行的解决方案。所以它来了:
一种根本不同的方法是将授权设计为依赖于核心子域的支持子域。这样,您就可以使用核心模型来定义访问权限,这使得它变得更加简单易懂。
例如,博客系统的授权机制可以使用来自核心域的作者、Post、版主等概念。如果您有复杂的授权要求,这是一个巨大的胜利。
与通用子域方法相比,明显的权衡是授权不是通用的,而是绑定到特定的子域。对于特定项目来说,这可能是可接受的,也可能是不可接受的,但对于不需要单独的、可重复使用的授权机制的小型系统来说,这是一种务实的方法。