ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

c#-有比使用IAsyncActionFilter进行授权的更好的方法,如果用户是角色或用户ID在特定记录的数据库中

2019-10-25 11:08:14  阅读:1624  来源: 互联网

标签:asp-net-core asp-net-core-mvc asp-net-identity c


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

1.用户具有“ TaskAdmin”角色

要么

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

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

>创建2种方法.一种具有属性[Authorize(Roles =“ TaskAdmin”)],另一种将检查用户是否对数据库对象负责.
>创建一个IAsyncActionFilter,它同时检查需求和要在控制器方法上使用的TypeFilterAttribute.

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

解决方法:

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

是.您可以使用Policy Based Authorization实施复杂的基于权限的规则.

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;
    }
}

启动文件

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

标签:asp-net-core,asp-net-core-mvc,asp-net-identity,c
来源: https://codeday.me/bug/20191025/1928063.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有