首页 文章

使用Loopback中的访问控制列表来限制对表记录的访问

提问于
浏览
0

我们正在使用Loopback for Node.js RESTful API . 我们想知道我们是否可以利用模型上的先天访问控制列表属性来限制对特定用户的某些记录/对象的访问 . 我希望这是可能的,我们不需要实现自己的逻辑 . 假设我们有两个这样的表(在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    |

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

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

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

1 回答

  • 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,它仅适用于原型方法调用 .

相关问题