是否有比使用IAsyncActionFilter来授权用户充当特定记录或用户ID在数据库中的特定记录更好的方法 [英] Is there a better way than using an IAsyncActionFilter to authorize if user is in role or user id is in database for specific record

查看:372
本文介绍了是否有比使用IAsyncActionFilter来授权用户充当特定记录或用户ID在数据库中的特定记录更好的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要求: 有一些控制器方法只能在以下情况下调用:

Requirement: There are some controller methods which only can be called if:

1.用户的角色为"TaskAdmin"

OR

2.用户负责将在控制器方法中修改的数据库对象(只有一列需要比较的用户ID).此数据表中的记录可以更改,并且不能硬编码".

我知道解决此问题的两种可能性:

  1. 创建2个方法.一种具有属性[Authorize(Roles = "TaskAdmin")],另一种将在属性中检查用户是否对数据库对象负责.

  1. Create 2 methods. One with the attribute [Authorize(Roles = "TaskAdmin")] and one where it will be checked if the user is responsible for the database object.

创建一个IAsyncActionFilter来同时检查需求和TypeFilterAttribute以便在控制器方法上使用.

Create an IAsyncActionFilter which checks both requirements and a TypeFilterAttribute to use on the controller methods.

(使用ASP.NET Core)有更好的方法吗?

推荐答案

是否有更好的方法(使用ASP.NET Core)?

Is there a better way to do this (with ASP.NET Core)?

是的.您可以使用基于策略的授权来实现复杂的权限基于规则.

Yes. You can use Policy Based Authorization to implement complex permission-based rules.

public class RecordOwnerRequirement : IAuthorizationRequirement
{
}

public class RecordOwnerHandler : AuthorizationHandler<RecordOwnerRequirement>
{
    private readonly ApplicationDbContext dbContext;
    private readonly IActionContextAccessor actionContextAccessor;

    public RecordOwnerHandler(ApplicationDbContext dbContext, IActionContextAccessor actionContextAccessor)
    {
        this.dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
        this.actionContextAccessor = actionContextAccessor ?? throw new ArgumentNullException(nameof(actionContextAccessor));
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RecordOwnerRequirement requirement)
    {
        if (IsUserAuthorized(context))
        {
            context.Succeed(requirement);
        }

        //TODO: Use the following if targeting a version of
        //.NET Framework older than 4.6:
        //      return Task.FromResult(0);
        return Task.CompletedTask;
    }

    private bool IsUserAuthorized(AuthorizationHandlerContext context)
    {
        var id = this.actionContextAccessor.ActionContext.RouteData.Values["id"];

        // Use the dbContext to compare the id against the database...

        // Return the result
        return true;
    }
}

Startup.cs

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    //*********************************************************************
    // Add policy for record owner 
    services.AddAuthorization(options =>
    {
        options.AddPolicy("RecordOwner", policy =>
            policy.Requirements.Add(new RecordOwnerRequirement()));
    });
    //*********************************************************************

    // Add application services.
    services.AddTransient<IEmailSender, EmailSender>();

    //*********************************************************************
    // Register record owner handler with the DI container 
    services.AddTransient<IAuthorizationHandler, RecordOwnerHandler>();
    services.AddTransient<IActionContextAccessor, ActionContextAccessor>();
    //*********************************************************************

    services.AddMvc();
}

用法

public class HomeController : Controller
{
    [Authorize(Roles = "TaskAdmin", Policy = "RecordOwner")]
    public IActionResult Contact()
    {
        ViewData["Message"] = "Your contact page.";

        return View();
    }
}

这篇关于是否有比使用IAsyncActionFilter来授权用户充当特定记录或用户ID在数据库中的特定记录更好的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆