环回 ACL "Authorization Required"
Loopback ACL "Authorization Required"
我正在使用 Loopback3。我 运行 遇到了我的 ACL 角色的问题,我不确定我做错了什么。我希望特定角色的用户能够将数据写入端点,但出于某种原因,我设置的用户(处于其中一个角色)无法写入。我收到“需要授权”错误。
我有 4 个角色:
- 管理员
- 内部
- 外部
- 机器人
对于此端点,所有经过身份验证的用户都可以读取数据,但只有管理员、内部和 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 请求时,我收到 'Authorization Required' 错误,即使是从资源管理器界面执行此操作也是如此。我可以毫无问题地执行 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;
});
});
});
};
角色和动态 roles/states($everyone 和 $authenticated)之间存在差异,而您的角色存储在 table 中以保持与用户 $everyone 和 $authenticated 的关联只是用户的一种状态。如果正确,请查看名为 "RoleMapping" 的 table。此外,如果您有自定义角色,请创建自定义 RoleResolver。
确实有很好的文档,在 Loopback 3 中入门真的不难。
https://loopback.io/doc/en/lb3/Defining-and-using-roles.html
这个例子让我对一般角色有了很好的理解:
这是一个完整的项目,因此您也可以在那里查看模型。
你的两个 table 应该是这样的:
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 table。
首先添加角色table、
中的所有角色
现在创建用户并在角色映射中添加该用户的条目 table 并为其分配一个 roleID,请参阅上面的代码,其中 roleId 1 表示管理员角色。
实际上,您的代码存在一些语法和逻辑错误!
- app.models.RoleMapping.USER 而不是 app.models.RoleMapping.user(如@Farid 所说)。
- loopback acl 中没有"DELETE" accessType。您应该使用“*”、"READ"、"WRITE" 或 "EXECUTE" 作为 accesType 值。 "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"]
}
]
- 最后,确保正确执行角色和角色映射。
我遇到的主要问题与以下项目有关:
使用 app.models.RoleMapping.USER
而不是 app.models.RoleMapping.user
(早期在代码库中已更改)
使用principalId
代替principalID
由于其他 ACL 因无法正常工作而在一段时间前已从应用程序中删除,我无法说明它们是否也导致了问题,但我会在过去添加它们确保为 LB3 使用正确的权限。
我正在使用 Loopback3。我 运行 遇到了我的 ACL 角色的问题,我不确定我做错了什么。我希望特定角色的用户能够将数据写入端点,但出于某种原因,我设置的用户(处于其中一个角色)无法写入。我收到“需要授权”错误。
我有 4 个角色:
- 管理员
- 内部
- 外部
- 机器人
对于此端点,所有经过身份验证的用户都可以读取数据,但只有管理员、内部和 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 请求时,我收到 'Authorization Required' 错误,即使是从资源管理器界面执行此操作也是如此。我可以毫无问题地执行 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;
});
});
});
};
角色和动态 roles/states($everyone 和 $authenticated)之间存在差异,而您的角色存储在 table 中以保持与用户 $everyone 和 $authenticated 的关联只是用户的一种状态。如果正确,请查看名为 "RoleMapping" 的 table。此外,如果您有自定义角色,请创建自定义 RoleResolver。
确实有很好的文档,在 Loopback 3 中入门真的不难。
https://loopback.io/doc/en/lb3/Defining-and-using-roles.html
这个例子让我对一般角色有了很好的理解:
这是一个完整的项目,因此您也可以在那里查看模型。
你的两个 table 应该是这样的:
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 table。
首先添加角色table、
中的所有角色现在创建用户并在角色映射中添加该用户的条目 table 并为其分配一个 roleID,请参阅上面的代码,其中 roleId 1 表示管理员角色。
实际上,您的代码存在一些语法和逻辑错误!
- app.models.RoleMapping.USER 而不是 app.models.RoleMapping.user(如@Farid 所说)。
- loopback acl 中没有"DELETE" accessType。您应该使用“*”、"READ"、"WRITE" 或 "EXECUTE" 作为 accesType 值。 "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"]
}
]
- 最后,确保正确执行角色和角色映射。
我遇到的主要问题与以下项目有关:
使用
app.models.RoleMapping.USER
而不是app.models.RoleMapping.user
(早期在代码库中已更改)使用
principalId
代替principalID
由于其他 ACL 因无法正常工作而在一段时间前已从应用程序中删除,我无法说明它们是否也导致了问题,但我会在过去添加它们确保为 LB3 使用正确的权限。