我正在使用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;
});
});
});
};
答案 0 :(得分:1)
我遇到的主要问题围绕以下各项:
使用app.models.RoleMapping.USER
代替app.models.RoleMapping.user
(早期在代码库中进行了更改)
使用principalId
代替principalID
由于其他ACL已经从应用程序中删除了,因为它们不能正常工作,我无法说明它们是否也在解决问题,但我会将它们添加到确保使用LB3的正确权限的时间。
答案 1 :(得分:0)
角色和动态角色/状态($ everyone和$ authenticated)之间存在差异,而您的角色存储在表中以保持与用户的关联$ everyone和$ authenticated只是用户的状态。查看名为" RoleMapping"的表,如果这是正确的。此外,如果您有自定义角色,请创建自定义RoleResolver。
确实有很好的文档,在Loopback 3中开始并不难。
https://loopback.io/doc/en/lb3/Defining-and-using-roles.html
这个例子让我对角色有了很好的理解:
这是一个完整的项目,所以你也可以查看那里的模型。
答案 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)
实际上,您的代码存在一些语法和逻辑错误!
更改以下代码的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"]
}
]