【问题标题】:How to add authorization with per-item based permissions to REST API endpoints in ASP.NET Core如何在 ASP.NET Core 中向 REST API 端点添加基于每个项目的权限的授权
【发布时间】:2022-01-07 22:52:10
【问题描述】:

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

Startup.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();
}

但是,我需要知道 Storage 用户正在尝试修改的 id 以确定是否应该允许他这样做 - 因此,它不能在 Authorize 中硬编码基于声明的属性或策略。 显然,我可以简单地检查方法本身内部的内容 - 毕竟,它将具有执行此授权所需的所有信息。但是,这种方式给这些方法中的每一个都添加了很多样板代码,我认为这并不理想。

除了将这个逻辑放入端点方法之外,还有什么更简洁的方式来实现这种授权?

【问题讨论】:

    标签: c# rest asp.net-core authorization asp.net-core-webapi


    【解决方案1】:

    您好,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();
    }
    

    如果要使用 Policy ,可以在 Policy 中添加 Role 授权。

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

    【讨论】:

    • 不幸的是,这不是我需要的。我最终创建了自定义策略、要求和处理程序——所有这些只是为了我可以将IHttpContextAccessor 注入它们,以便检查路由值是否与给定存储中的用户角色匹配。我尝试过使用标准的“角色”声明,但这还不够。
    • 您好,您想在自定义策略中添加角色授权吗?
    • 我已经编辑了我的答案,您可以根据需要添加不同的Policy并在这些Policy中添加角色授权
    猜你喜欢
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 2018-09-06
    相关资源
    最近更新 更多