Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 若用户在角色中或用户id在特定记录的数据库中,是否有比使用IAsyncationFilter更好的方法来授权_C#_Asp.net Core_Asp.net Core Mvc_Asp.net Identity - Fatal编程技术网

C# 若用户在角色中或用户id在特定记录的数据库中,是否有比使用IAsyncationFilter更好的方法来授权

C# 若用户在角色中或用户id在特定记录的数据库中,是否有比使用IAsyncationFilter更好的方法来授权,c#,asp.net-core,asp.net-core-mvc,asp.net-identity,C#,Asp.net Core,Asp.net Core Mvc,Asp.net Identity,要求: 有些控制器方法只能在以下情况下调用: 一,。用户具有角色“TaskAdmin” 或 二,。用户负责将在控制器方法中修改的数据库对象(只有一列具有要比较的用户id)。此数据表中的记录可以更改,并且不是“硬编码”的 我知道解决这个问题的两种可能性: 创建两个方法。一个具有属性[Authorize(Roles=“TaskAdmin”)],并且将在其中检查用户是否负责数据库对象 创建一个IAsyncationFilter,用于检查控制器方法上使用的要求和TypeFilterAttribute 是

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

一,。用户具有角色“TaskAdmin”

二,。用户负责将在控制器方法中修改的数据库对象(只有一列具有要比较的用户id)。此数据表中的记录可以更改,并且不是“硬编码”的

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

  • 创建两个方法。一个具有属性
    [Authorize(Roles=“TaskAdmin”)]
    ,并且将在其中检查用户是否负责数据库对象

  • 创建一个
    IAsyncationFilter
    ,用于检查控制器方法上使用的要求和
    TypeFilterAttribute

  • 是否有更好的方法(使用ASP.NET Core)实现此目的?

    有没有更好的方法(使用ASP.NET Core)来实现这一点

    对。您可以使用来实现复杂的基于权限的规则

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

    我已经用从请求中获取
    id
    参数的解决方案更新了我的答案。
    // 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();
        }
    }