【问题标题】:Loopback ACL "Authorization Required"环回 ACL“需要授权”
【发布时间】:2017-03-29 03:20:59
【问题描述】:

我正在使用 Loopback3。我的 ACL 角色遇到了问题,我不确定我做错了什么。我希望具有特定角色的用户能够将数据写入端点,并且由于某种原因,我设置的用户(处于这些角色之一)无法写入。我收到需要授权错误。

我有 4 个角色:

  • 管理员
  • 内部
  • 外部
  • 机器人

对于此端点,所有经过身份验证的用户都可以读取数据,但只有 admin、internal 和 bot 用户可以写入数据,并且只有 admin 用户可以删除数据。

这是我定义 ACL 的方式:

"acls": [
    {
        "accessType": "*",
        "principalType": "ROLE",
        "principalId": "$everyone",
        "permission": "DENY"
    },
    {
        "accessType": "READ",
        "principalType": "ROLE",
        "principalId": "$authenticated",
        "permission": "ALLOW"
    },
    {
        "accessType": "WRITE",
        "principalType": "ROLE",
        "principalId": "admin",
        "permission": "ALLOW"
    },
    {
        "accessType": "WRITE",
        "principalType": "ROLE",
        "principalId": "internal",
        "permission": "ALLOW"
    },
    {
        "accessType": "WRITE",
        "principalType": "ROLE",
        "principalId": "bot",
        "permission": "ALLOW"
    },
    {
        "accessType": "DELETE",
        "principalType": "ROLE",
        "principalId": "admin",
        "permission": "ALLOW"
    }
],

我设置了两个用户,一个是机器人,一个是管理员。当我为任一用户向 API 发出 POST 请求时,我会收到“需要授权”错误,即使是从资源管理器界面执行此操作也是如此。我可以毫无问题地执行 GET,但 POST 会失败。

如果我删除所有“WRITE” acl 并用它替换它们,则执行 POST 即可。

    {
        "accessType": "WRITE",
        "principalType": "ROLE",
        "principalId": "$authenticated",
        "permission": "ALLOW"
    },

所以,我可以实现它,但我不知道为什么我的自定义角色会失败。

编辑:这是我创建用户的方式,因为我实际上还没有构建任何类型的界面。

module.exports = function (app) {
    let today = new Date();

    let admin = {
        name: 'admin',
        description: 'admin users',
        created: today.toJSON(),
        modified: today.toJSON()
    };

    let internal = {
        name: 'internal',
        description: 'Internal users',
        created: today.toJSON(),
        modified: today.toJSON()
    };

    let external = {
        name: 'external',
        description: 'external users',
        created: today.toJSON(),
        modified: today.toJSON()
    };

    let bot = {
        name: 'bot',
        description: 'robots',
        created: today.toJSON(),
        modified: today.toJSON()
    };

    let model = app.models.user;

    model.create([
        {username: 'bot', email: 'example@example.com', password: 'test123'},
        {username: 'admin', email: 'example2@example.com', password: 'test123'},
        {username: 'iAdmin', email: 'example3@example.com', password: 'test123'},
        {username: 'eUser', email: 'example4@example.com', password: 'test123'},
    ], function(err, users) {
        if (err) throw err;

        app.models.Role.create(bot, function (err, botRole) {
            if (err) throw err;

            botRole.principals.create({principalType: app.models.RoleMapping.user, principalID: users[0].id}, function(err, principal) {
                if (err) throw err;
            });
        });

        app.models.Role.create(admin, function (err, adminRole) {
            if (err) throw err;

            adminRole.principals.create({principalType: app.models.RoleMapping.user, PrincipalID: users[1].id}, function(err, principal) {
                if (err) throw err;
            });
        });

        app.models.Role.create(admin, function (err, internalRole) {
            if (err) throw err;

            internalRole.principals.create({principalType: app.models.RoleMapping.user, PrincipalID: users[2].id}, function(err, principal) {
                if (err) throw err;
            });
        });

        app.models.Role.create(external, function (err, externalRole) {
            if (err) throw err;

            externalRole.principals.create({principalType: app.models.RoleMapping.user, PrincipalID: users[3].id}, function(err, principal) {
                if (err) throw err;
            });
        });
    });
};

【问题讨论】:

  • 可能问题出在您创建角色并将其与用户关联的位置。
  • 可能我已经添加了用于创建用户的脚本。
  • 我相信他们应该是app.models.RoleMapping.USER而不是app.models.RoleMapping.user
  • 好收获!我为此进行了更改,但它似乎仍然没有影响任何东西。
  • 这就像 Loopback 已经拥有的动态角色(如 $everyone$authenticated)工作得很好,但我所有的自定义角色都被忽略了。

标签: acl loopbackjs strongloop loopback


【解决方案1】:

我遇到的主要问题围绕以下几项:

  1. 使用app.models.RoleMapping.USER 代替app.models.RoleMapping.user(早期代码库中已更改)

  2. 使用principalId 而不是principalID

由于其他 ACL 前一段时间由于它们无法正常工作而从应用程序中删除,我无法说明它们是否也导致了问题,但我会随着时间的推移添加它们确保为 LB3 使用正确的权限。

【讨论】:

  • 顺便问一下问题是什么?我知道这是一个古老的问题和答案,但我面临着类似的问题。
  • @PrivateOmega 如果我没记错的话,这只是 LoopBack 对案件感到不安。正如我在第 1 点中所述,我需要使用 USER 而不是 user 等。
【解决方案2】:

角色和动态角色/状态($everyone 和 $authenticated)之间存在区别,而您的角色存储在表中以保持与用户 $everyone 的关联,而 $authenticated 只是用户的状态。如果正确,请查看名为“RoleMapping”的表。此外,如果您有自定义角色,请创建自定义 RoleResolver。

有非常好的文档,而且在 Loopback 3 中入门并不难。

https://loopback.io/doc/en/lb3/Defining-and-using-roles.html

这个例子让我对一般角色有了很好的理解:

https://github.com/strongloop/loopback-example-access-control/blob/master/server/boot/role-resolver.js

这是一个完整的项目,因此您也可以在那里查看模型。

【讨论】:

    【解决方案3】:

    这就是你的两个表的样子:

    GET role -->> [table - role]
    
    [
      {
        "roleId": 1,
        "name": "admin",
        "description": "admin",
        "created": "2016-08-23T16:46:07.572Z",
        "modified": "2016-08-23T16:46:07.572Z"
      },
      {
        "roleId": 2,
        "name": "internal",
        "description": "internal",
        "created": "2016-08-23T16:46:07.574Z",
        "modified": "2016-08-23T16:46:07.574Z"
      }
    ]
    
    
    Get Role Mapping  [table- user-role]-->>
    
    [
      {
        "userRoleId": 123,
        "roleId": 2, //id of role i.e. 1 for admin 
        "principalType": "USER",
        "principalId": "1234",
        "created": null,
        "modified": null
      },
      ..
      ...
    ]
    

    所以通过查看您的代码,我可以说您没有将 roleId 添加到 roleMapping 表中。

    首先在角色表中添加所有角色,

    现在创建用户并在角色映射表中添加该用户的条目并为其分配一个roleID,参见上面的代码,其中roleId 1 表示管理员角色。

    【讨论】:

    • 我的 RoleMapping 表填充了 roleId 字段,但没有填充 principalId 字段。
    【解决方案4】:

    其实你的代码有一些语法和逻辑错误!

    1. app.models.RoleMapping.USER 而不是 app.models.RoleMapping.user(正如@Farid 所说)。
    2. 环回 acl 中没有“DELETE”访问类型。您应该使用“*”、“READ”、“WRITE”或“EXECUTE”作为访问类型值。 “WRITE”支持“create”、“updateAttributes”、“upsert”和“destroyById”资源。 (更多详情见loopback documentation)。

    修改acl如下代码:

    "acls": [ { "accessType": "*", "principalType": "ROLE", "principalId": "$everyone", "permission": "DENY" }, { "accessType": "READ", "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW" }, { "accessType": "*", "principalType": "ROLE", "principalId": "admin", "permission": "ALLOW" }, { "principalType": "ROLE", "principalId": "internal", "permission": "ALLOW", "property": ["create", "updateAttributes", "upsert"] }, { "principalType": "ROLE", "principalId": "bot", "permission": "ALLOW", "property": ["create", "updateAttributes", "upsert"] } ]

    1. 最后,确保正确执行角色和角色映射。

    【讨论】:

      猜你喜欢
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多