如何在 Loopback 中使用 checkAccessForContext

How to use checkAccessForContext in Loopback

我有

common/models/list.json

...
  "acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "find"
    },
    {
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "create"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW"
    }
  ],
...

当我使用 id 1 执行 GET /lists/{id} 时(我的令牌是此列表的所有者),我的列表有 200 个响应。没关系。

但是,当我在应用程序中拨打电话时

app.models.ACL.checkAccessForContext({
              principals: [{
                type: 'ROLE',
                id: '$owner'
              }],
              model: 'List',
              id: 1,
              property: '*',
              accessType: 'READ'
            }, (error, request) => {
              console.log(request);
            });

我有 request.permission === 'DENY'。为什么会这样? 我通过了正确的校长吗?

感谢您的帮助。

你的代码没问题。这是一个bug(#2153) in loopback. I have made a pull request。现在你可以 monkey-patch 方法,直到错误修复被合并:

const { AccessRequest } = require('loopback/lib/access-context');

ACL.resolvePermission = function resolvePermission(acls, req) {
    if (!(req instanceof AccessRequest)) {
      req = new AccessRequest(req);
    }
    // Sort by the matching score in descending order
    acls = acls.sort(function(rule1, rule2) {
      return ACL.getMatchingScore(rule2, req) - ACL.getMatchingScore(rule1, req);
    });
    var permission = ACL.DEFAULT;
    var score = 0;

    for (var i = 0; i < acls.length; i++) {
      var candidate = acls[i];
      score = ACL.getMatchingScore(candidate, req);
      if (score < 0) {
        // the highest scored ACL did not match
        break;
      }
      if (!req.isWildcard()) {
        // We should stop from the first match for non-wildcard
        permission = candidate.permission;
        break;
      } else {
        if (req.exactlyMatches(candidate)) {
          permission = candidate.permission;
          break;
        }
        // For wildcard match, find the strongest permission
        var candidateOrder = AccessContext.permissionOrder[candidate.permission];
        var permissionOrder = AccessContext.permissionOrder[permission];
        if (candidateOrder > permissionOrder) {
          permission = candidate.permission;
           //@issuehere
          break; //This is the fix
        }
      }
    }

    if (debug.enabled) {
      debug('The following ACLs were searched: ');
      acls.forEach(function(acl) {
        acl.debug();
        debug('with score:', acl.score(req));
      });
    }

    var res = new AccessRequest(req.model, req.property, req.accessType,
        permission || ACL.DEFAULT);
    return res;
  };