环回ACL“需要授权”

时间:2017-02-13 20:27:54

标签: acl loopbackjs strongloop loopback

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

我有4个角色:

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

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

以下是我如何定义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;
            });
        });
    });
};

4 个答案:

答案 0 :(得分:1)

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

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

  2. 使用principalId代替principalID

  3. 由于其他ACL已经从应用程序中删除了,因为它们不能正常工作,我无法说明它们是否也在解决问题,但我会将它们添加到确保使用LB3的正确权限的时间。

答案 1 :(得分:0)

角色和动态角色/状态($ 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

这是一个完整的项目,所以你也可以查看那里的模型。

答案 2 :(得分:0)

这就是你的两张桌子的样子:

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表示管理员角色。

答案 3 :(得分:0)

实际上,您的代码存在一些语法和逻辑错误!

  1. app.models.RoleMapping.USER而不是app.models.RoleMapping.user(正如@Farid所说)。
  2. 没有" DELETE" loopback acl中的acceessType。你应该使用" *"," READ"," WRITE"或"执行"对于accesType值。 " WRITE"支持"创建"," updateAttributes"," upsert"和" destroyById" resoueces。 (loopback documentation)中的详细信息。
  3. 更改以下代码的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. 最后,确保正确执行role和roleMapping。