如何向ASP.NET Core中的REST API端点添加具有基于项目的权限的授权



我的API假设称为存储库的集合,这些存储库保存项目-这些项目可以添加、编辑或从存储库中删除。一个用户可以是多个存储的成员,并且可以在给定的存储中担任三个可能的角色之一——编辑器、注释器和查看器。我已经通过JWT实现了身份验证-现在我需要添加授权,因此某些操作只能由具有适当角色的特定存储的成员执行-例如,添加项目应该只能由Editors执行。起初,我想到了最简单的方法,即创建自定义策略并为端点添加适当的属性:

启动.cs

services.AddAuthorization
(
options =>
{
options.AddPolicy
(
"StorageEditor",
policy => policy.RequireClaim("StorageEditor", "{storageId}") // I need to know the id of storage request is associated with
);
}
);

ItemsController.cs

// Id of storage in question is part of the route
[HttpPost("storages/{storageId}/items")]
[Authorize(Policy = "StorageEditor")
public async Task<ActionResult> CreateItem(
[FromRoute(Name = "storageID")] int storageId)
{
return Ok();
}

但是,我需要知道存储用户试图修改的id,以便决定是否允许他这样做——因此,它不能硬编码在Authorize属性或基于声明的策略中。显然,我可以简单地在方法本身内部进行检查——毕竟,它将拥有执行此授权所需的所有信息。然而,这种方式为每个方法添加了大量样板代码,我认为这并不理想。

有没有比把这个逻辑扔到端点方法中更干净的方法来实现这样的授权?

Hi,ASP.NET Core中基于角色的授权,您可以在JWT方法中自行添加角色,并在操作中直接使用这些角色

在JWT方法中:

// Add roles as multiple claims
foreach(var role in user.Roles) 
{
claims.Add(new Claim(ClaimTypes.Role, role.Name));

// these also work - and reduce token size
// claims.Add(new Claim("roles", role.Name));
// claims.Add(new Claim("role", role.Name));
}

然后您可以将[Authorize(Roles= "xxx")]添加到控制器中的操作:

[Authorize(Roles= "xxx")]
public async Task<ActionResult> CreateItem(
[FromRoute(Name = "storageID")] int storageId)
{
return Ok();
}

如果要使用策略,可以在策略中添加角色授权。

Services.AddAuthorization(option =>
{
option.AddPolicy("PolicyName", x =>
{
//....any other attribute you want....
//Add Role authorization
x.RequireRole("Admin","xx",...);
});
});

最新更新