如何在Loopback中使用checkAccessForContext

时间:2017-02-11 13:37:54

标签: node.js loopbackjs strongloop 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"
    }
  ],
...

当我使用/lists/{id} 1获取id时(我的令牌是此列表的所有者)我已经获得了200个响应的列表。没关系。

但是,当我在app中打电话时

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

我已经request.permission === 'DENY'了。它为什么会发生? 我通过了正确的校长吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

你的代码很好。这是环回中的bug(#2153)。我为它做了一个pull request。现在你可以修补方法,直到bugfix合并为止:

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;
  };