角色动态授权 asp.net core

Posted

技术标签:

【中文标题】角色动态授权 asp.net core【英文标题】:Dynamic authorization of roles asp.net core 【发布时间】:2017-12-01 08:39:21 【问题描述】:

这不是一个重复的问题,或者说其他解决方案中给出的解决方案没有奏效。

假设有一个控制器

[Authorize(Roles=//set dynamically)]
public IActionResult DashBoard(LoginModel model)


我已经尝试了以下问题的解决方案

    Add roles to authorize attribute

    dynamically assign controller action permissions to roles

    dynamically add roles to authorize attribute for controller(错误:句柄方法 - 找不到合适的方法来覆盖)

    can policy based authorization be more dynamic

所有这些解决方案都不起作用,因为接口中覆盖的方法不存在(例如,authorizeAttribute 不包含 AuthorizeCore 的定义),或者在某些情况下 IServiceCollection 服务不包含特定方法

【问题讨论】:

这里的答案真的是一个好...***.com/a/31465227/4755704 我已经试过了。未找到 AuthorizationContext 定义,对于句柄方法,它说没有找到合适的方法来覆盖 参考github.com/VahidN/DNTIdentity 【参考方案1】:

你不能那样做。 [Authorize(Roles=//set dynamically)] 必须在编译时知道。出于这个原因,也不鼓励使用角色,正如来自 cmets 的 blowdart 链接帖子中所指出的那样。

相反,您应该使用声明和政策。声明是细粒度的权限,例如“CreateCustomer”或“DeleteCustomer”或“ViewDashboard”。

所以你必须像使用它一样

[Authorize(Policy = "ViewDashboard")]

需要在编译时了解这些策略。

public class ViewDashboardRequirement : AuthorizationHandler<ViewDashboardRequirement>, IAuthorizationRequirement

    public override void Handle(AuthorizationContext context, ViewDashboardRequirement requirement)
    
        if (context.User.HasClaim(c => c.Type == "dashboard:read"))
        
            context.context.Succeed(requirement);
            return;
        

        // only call fail if you do not want that other AuthorizationHandler may succeed with 
        // a different requirement
        // context.Fail();
    

有关如何生成通用处理程序(而不是为每个策略编写新处理程序)的示例,请参阅我的回答 here。

这将允许您创建可配置的角色。现在您可以创建由声明包组成的角色。每个索赔可能是一个政策。当用户登录时,您将属于某个角色的声明添加到用户声明列表中。

支持:ViewDashboard、ViewCustomers、ViewContacts、ManageCases(支持票证) 经理:ViewDashboard、ManageCustomers(查看、编辑、删除)、ManageContacts(查看、编辑、删除) 管理员:ManageDashboard(查看、编辑)

等等。

从评论更新。

您应该能够利用 ASP.NET Core Identity 的声明和角色声明功能而无需更改一行代码,因此您拥有 IdentityRoleIdentityRoleClaim 类。在运行时,您添加一个新的IdentityRole(即“经理”),然后添加多个IdentityRoleClaim(每个权限/策略一个)

【讨论】:

我面临的问题是在需求类中我需要调用 db.我需要为此添加一个数据上下文。但是这个类创建的任何对象都需要一个 datacontecxt 对象 不,你不需要在那里调用 db。要求应该对用户声明进行操作。登录时,您将所需的声明放入ClaimsPrinicipal。然后,每次用户进行身份验证时,您都可以从HttpContext.User.HasClaim(...)HttpContext.User.FindFirst(...) 中访问声明。那么一个角色只是一堆可以在运行时配置的声明(即添加新角色意味着创建一个角色并向其添加某些声明 “声明”比“ViewCustomers”或“ManageCustomers”等特定权限多一点 @Lobato:声明在那里查看他们是否有权访问页面/webapi。要筛选数据,您需要数据库上的一些标准,例如“ownedBy”和“groupId”、组织 ID 或将其与父组织进行比较(如果您有类似于 Microsoft Dynamics 管理数据访问的方式)。您如果您根据角色调整视图,则可以有一个带有角色名称或 id 的声明数组,但这假设您在编译时知道角色。这就是为什么使用AuthorizeAttributeRoles 属性不再推荐了。声明更具动态性。 @Lobato:好吧。在您的 DashController/actions 上,您有 [Authorize(Policy = "ViewDashboard")] 用于检查用户是否有 dashboard:view 策略。不管他属于哪个组,只要他有声明,他就可以访问那个动作或控制器。在其中,您需要阅读他的 groupis、groupids、userid、他所属的公司或您需要的任何内容(无论是从声明中还是从他的 id 中获取并从您的数据库中获取)并将其应用于数据或数据库查询【参考方案2】:

如果角色授权,我认为您必须使用 Policy。 事实上,基于策略与基于角色的好处之一就是这一点。

【讨论】:

【参考方案3】:
public IActionResult Validate(LoginDetails userobj)
       
          LoginDetails user = new LoginDetails();
         var checklogin = from s in appDbContext.loginDetails where s.UserName == userobj.UserName && s.Password == userobj.Password select s;

               if (checklogin != null && checklogin.Count() > 0)
               
                   if (checklogin.FirstOrDefault().Role == 1)
                   
                       return RedirectToAction("Home");
                   
                   else if (checklogin.FirstOrDefault().Role == 2)
                   
                       var UserId = checklogin.FirstOrDefault().LoginId;
                       HttpContext.Session.SetInt32("UserId", UserId);
                       return RedirectToAction("Index1");
                    
           

           return RedirectToAction("Failed");
       

【讨论】:

请在您的回答中添加口头描述。

以上是关于角色动态授权 asp.net core的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC - 动态授权

MVC 3 ASP.NET 角色-授权属性

ASP.NET Core按用户角色授权

Asp.net核心身份声明与基于角色的授权[重复]

ASP.NET MVC 角色授权

ASP.Net MVC 5 - 使用角色授权错误