【问题标题】:using Access Control Lists in Loopback for restricting access to table records在 Loopback 中使用访问控制列表来限制对表记录的访问
【发布时间】:2016-09-23 20:14:01
【问题描述】:

我们正在为 Node.js RESTful API 使用 Loopback。我们想知道我们是否可以利用模型上天生的访问控制列表属性来限制某些用户只能访问某些记录/对象。我希望这是可能的,并且我们不需要实现自己的逻辑。假设我们有两个这样的表(在 Postgres 中):

contracts
| id | name | manager_id |
|----|------|-------------|
| 1  | a    | 4           |
| 2  | b    | 5           |
| 3  | c    | 6           |

contract_managers
| id | name |
|----|------|
| 4  | e    |
| 5  | f    |
| 6  | g    |

我们想要的是实现对contracts 表的低级别访问控制——限制用户只能访问某些记录。鉴于文档,尚不清楚我们是否可以仅使用 ACL 来限制对特定记录的访问。

如果有人登录到我们的应用程序并且他们是contract_manager,我们希望他们只能从contracts 表中读取manager_id 是登录用户ID 的记录。例如,如果我已登录并且我的用户 id = 4,那么我就是一个 contract_manager,我应该只能从 manager_id = 4 的contracts 表中读取数据。

有没有办法用 ACL 实现这个简单的逻辑?还是我们需要创建自定义逻辑?

【问题讨论】:

    标签: node.js acl loopbackjs data-access-layer


    【解决方案1】:

    如果您定义custom role resolver,然后添加一个具有该角色限制特定访问权限的 ACL 条目,则可以执行此操作。

    Role.registerResolver('$manager', function (role, ctx, callback) {
      if (ctx.modelName === 'Contract') {
        app.models.Contract.count({
          id: ctx.modelId,
    
          // I'm assuming the ContractManager model extends User model.
          // If instead there's a relation between ContractManager and User,
          // Use include and scopes to filter it.
          managerId: ctx.accessToken.userId,
        }, function(err, count) {
          if (err) {
            callback(err);
          } else if (count) {
            callback();
          } else {
            callback(new Error('Not Manager'));
          }
        });
      } else if (ctx.modelName === 'ContractManager') {
    
        // Again making the same assumption about ContractManager. Chnage
        // accordingly.
        if (ctx.accessToken.userId === ctx.modelId) {
          callback();
        } else {
          process.nextTick(() => callback(new Error('Not Manager')));
        }
      } else {
        process.nextTick(() => callback(new Error('Only for ContractManager or Contract')));
      }
    }
    

    那么你必须添加这个acl(请随意使其更具体):

    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$manager",
      "permission": "ALLOW",
      "property": "*",
      "model": "*"
    }
    

    现在请注意,此角色解析器仅适用于原型方法(即 findById,/api/Contract/{id})而不适用于静态方法(即 find,/api/Contract),因为我们使用 ctx.modelId,它仅适用于原型方法调用。

    【讨论】:

      猜你喜欢
      • 2015-05-22
      • 2010-09-05
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多