获取AspNet用户RoleId以进行比较权限 [英] Getting AspNet Users RoleId for Comparison In permissions

查看:67
本文介绍了获取AspNet用户RoleId以进行比较权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个区域中将RoleId作为字符串保留在权限表中。我正在对ID进行比较,以提取角色的所有权限。我正在像这样获得当前的登录用户RoleId。

I have a area where the RoleId is kept as a string in the permissions table. I am doing a comparison on the Id to pull all permissions for the Role. I am getting the current Logged in user RoleId like this.

 var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
 string roleid = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId);

它不喜欢使用字符串。我正在

It does not like the usage of string. I am getting

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string'

这里是我进行比较的地方,请注意权限可以有UserId或RoleId,我没有

Here is where i am doing the comparison, Note the permission can have either UserId or RoleId, I do not have a problem for the UserId with this setup.

var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && String.IsNullOrEmpty(i.RoleId = roleid) && String.IsNullOrEmpty(i.UserId = userid));

是否有其他方法可以获取RoleId或使用不同的语言进行比较?

Is there a different way to get the RoleId or maybe different verbiage to do the compare?

谢谢

更新:下面添加了控制器。抱歉,它很长。.

Update: Added Controller below. Sorry it is long..

   protected override void OnActionExecuting(ActionExecutingContext context)
    {
        base.OnActionExecuting(context);
        try
        {
            //int roleid = int.Parse(Env.GetUserInfo("roleid"));
            //int userid = int.Parse(Env.GetUserInfo("userid"));
            string userid = User.Identity.GetUserId();
            //string userid = Env.GetUserInfo("userid");
            //string roleid = Env.GetUserInfo("roleid");
            var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            // Select will return collection as opposed to scalar/single value. Pay attention to datatype here. 
            IEnumerable<string> currentUserRoles = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId);
            //string roleid = roles;
            var descriptor = context.ActionDescriptor;
            var actionName = descriptor.ActionName.ToLower();
            var controllerName = descriptor.ControllerDescriptor.ControllerName.ToLower();
            var controller = descriptor.ControllerDescriptor.ControllerName;

            var GetOrPost = context.HttpContext.Request.HttpMethod.ToString();
            var checkAreaName = context.HttpContext.Request.RequestContext.RouteData.DataTokens["area"];
            string AreaName = "";
            if (checkAreaName != null)
            {
                AreaName = checkAreaName.ToString().ToLower() + "/";
            }

            var cacheItemKey = "AllMenuBar";

            var global = HttpRuntime.Cache.Get(cacheItemKey);

            if (GetOrPost == "POST")
            {
                // Added index to string 02/03/2020
                // Added add to actonName settings 02/08/2020
                ///if menupermission create,edit,delete then update value "true" in IsMenuChange file
                if (controllerName == "menupermission" && (actionName == "add" || actionName == "index" || actionName == "create" || actionName == "edit" || actionName == "delete" || actionName == "multiviewindex"))
                {
                    global = MenuBarCache(cacheItemKey, global, "shortcache");
                }
            }

            if (global == null)//if cashe is null
            {
                global = MenuBarCache(cacheItemKey, global, "60mincache");//make cache from db
            }


            var menuaccess = (MenuOfRole[])global;

            if (GetOrPost == "GET")
            {
                if (actionName == "add" || actionName == "index" || actionName == "create" || actionName == "edit" || actionName == "delete" || actionName == "multiviewindex")
                {
                    // Old Impementation May be removed at Cleanup if not used - 02/10/2020
                    //ViewBag.Add = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsAdd));
                    //ViewBag.Read = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsRead));
                    //ViewBag.Create = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsCreate));
                    //ViewBag.Edit = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsUpdate));
                    //ViewBag.Delete = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsDelete))();

                    // Stack Overflow corrections - 02/10/2020
                    ViewBag.Add = menuaccess.Any(i => i.MenuURL == controllerName && i.IsAdd);
                    ViewBag.Read = menuaccess.Any(i => i.MenuURL == controllerName && i.IsRead);
                    ViewBag.Create = menuaccess.Any(i => i.MenuURL == controllerName && i.IsCreate);                        
                    ViewBag.Edit = menuaccess.Any(i => i.MenuURL == controllerName && i.IsUpdate);
                    ViewBag.Delete = menuaccess.Any(i => i.MenuURL == controllerName && i.IsDelete);
                    ViewBag.Visable = menuaccess.Any(i => i.MenuURL == controllerName && i.IsVisable);
                }
            }

            string menuUrl = AreaName + controllerName + "/" + actionName;

            if (IsActionNameEqualToCrudPageName(actionName))
            {
                menuUrl = AreaName + controllerName;
            }


            var checkUrl = menuaccess.FirstOrDefault(i => (i.MenuURL == AreaName + controllerName + "/" + actionName) || i.MenuURL == menuUrl);
            ///checkUrl: check if menu url Exists in MenuPermission if not exists then will be run
            if (checkUrl != null)
            {
                // Changed below line to use string instead of int..  01/26/2020
                //var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && String.IsNullOrEmpty(i.RoleId = roleid) && String.IsNullOrEmpty(i.UserId = userid));
                // Added change to use roles as collection.
                var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && currentUserRoles.Contains(i.RoleId) && i.UserId == userid);
                ///check menu  && roleid && userid
                if (checkControllerActionRoleUserId != null)
                {
                    if (IsActionNameEqualToCrudPageName(actionName))
                    {
                        CheckAccessOfPageAction(context, actionName, checkControllerActionRoleUserId);
                    }
                    else
                    {
                    if (checkControllerActionRoleUserId.IsRead == false || checkControllerActionRoleUserId.IsDelete == false || checkControllerActionRoleUserId.IsCreate == false || checkControllerActionRoleUserId.IsUpdate == false)//if userid !=null && Check Crud
                        {
                            UnAuthoRedirect(context);

                        }
                    }
                }
                else
                {

                    var checkControllerActionRole = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && currentUserRoles.Contains(i.RoleId) && i.UserId == null);
                    if (checkControllerActionRole != null)
                    {

                        if (IsActionNameEqualToCrudPageName(actionName))
                        {
                            CheckAccessOfPageAction(context, actionName, checkControllerActionRole);
                        }
                        else
                        {
                            if (checkControllerActionRole.IsRead == false || checkControllerActionRole.IsDelete == false || checkControllerActionRole.IsCreate == false || checkControllerActionRole.IsUpdate == false)//if userid !=null && Check Crud
                            {
                                UnAuthoRedirect(context);
                            }
                        }
                    }
                    else
                    {
                        if (IsThisAjaxRequest() == false)//if userid !=null && Check Crud
                        {
                            UnAuthoRedirect(context);
                        }

                    }


                }


            }


        }
        catch (Exception)
        { }
    }

更新:
在实现以下@Sam建议之后,我还需要找到一种方法,以不授予权限表中未包含的用户访问权限。为了避免冗余。如果用户无权访问某些内容,则无需将其添加到权限中以确保他们无权访问。如果用户登陆到他们无权访问的页面,我在下面的代码部分中添加了重定向到仪表板的功能。

UPDATE: After implementing What @Sam suggested below I also needed to find a way to not give access to users that are not in the permissions table. To avoid redundancy. If a user does not have access to something then i shouldn't need to add it to permissions to make sure they do not have access. I added to a section of below code to redirect to the Dashboard if a user lands on a page they do not have access to.

var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && currentUserRoles.Contains(i.RoleId)
&& (i.UserId == userid || i.UserId == null) || controllerName == "dashboard"// @Sam: This is how we can combine
    );
    ///check menu  && roleid && userid
    if (checkControllerActionRoleUserId != null)
      {
        if (IsActionNameEqualToCrudPageName(actionName))
          {
            CheckAccessOfPageAction(context, actionName, checkControllerActionRoleUserId);
          }
          else
          {
            if (checkControllerActionRoleUserId.IsRead == false || checkControllerActionRoleUserId.IsDelete == false || checkControllerActionRoleUserId.IsCreate == false || checkControllerActionRoleUserId.IsUpdate == false)//if userid !=null && Check Crud
             {
                UnAuthoRedirect(context);

             }
         }
      } 
      else
      {
        UnAuthorizedArea(context);
      }   


推荐答案

其中有几个问题您的代码。解决当前错误后,您将收到更多错误:

There are couple of issues in your code. After fixing the current error you will get more errors:


  1. 您正在将字符串集合分配给字符串(通过字符串roleid)。目前,您正在收到此错误。修复此错误后,错误就会出现。

出现错误的原因是:


  • 以下语句返回已登录用户的角色集合(准确地说是roleId集合),而不是单个角色ID。

  • The below statement returns collection of roles (roleId collection to be precise) of logged in user as opposed to single role id.

string roleid = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId);`


  • 然后,您尝试分配该角色标识集合到标量属性i。下一条语句中的RoleId(通过i.RoleId = roleid)

  • And then you are trying to assign this roleid collection to scalar property i.RoleId (via i.RoleId = roleid) in the next statement

    var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl &&  String.IsNullOrEmpty(i.RoleId = roleid) && String.IsNullOrEmpty(i.UserId = userid));`
    




    1. 使用赋值运算符=代替 == 进行比较。因此,您尝试将Roleid分配给i.RoleId,这是不允许的。

    1. Using assignment operator = instead of == for comparison. So, you are trying to assign roleid to i.RoleId which is not allowed.

    使用赋值运算符=而不是==进行比较。因此,您正在尝试将userid分配给i.UserId,这是不允许的。

    Using assignment operator = instead of == for comparison. So, you are trying to assign userid to i.UserId which is not allowed.


  • 修复::请按如下所示修改您的roleId部分:

    Fix: Please modify your roleId section as below:

    var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
    // Select will return collection as opposed to scalar/single value. Pay attention to datatype here. 
    IEnumerable<string> currentUserRoles = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId); 
    

    (OR)

    //You can use var in case you do not know the data types of result.
    var currentUserRoles = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId); 
    

    currentUserRoles将包含当前登录用户的所有角色。现在,按如下方式使用该集合(请注意条件 currentUserRoles.Contains(i.RoleId)。我也将条件固定在userid周围。):

    currentUserRoles will contain all the roles of current logged in user. Now use that collection as below (please notice the condition currentUserRoles.Contains(i.RoleId). I also fixed condition around userid.):

    var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl 
          && currentUserRoles.Contains(i.RoleId) && i.UserId == userid);
    

    或者,可以使用Where和FirstOrDefault拆分上述语句,如下所示:

    Alternatively, above statement can be split using Where and FirstOrDefault as follows:

    // Where statement returns collection of menuaccess items meeting all three conditions
    var filteredMenuAccessCollection = menuaccess.Where(i => i.MenuURL == menuUrl && currentUserRoles.Contains(i.RoleId) && i.UserId == userid);
    // FirstOrDefault will return the first menuaccess item from filteredMenuAccessCollection
    var checkControllerActionRoleUserId = filteredMenuAccessCollection.FirstOrDefault();
    

    以上内容可以进一步重写,如下所示:

    The above can further be re-written as follows:

    var mathingMenuUrlMenuAccessCollection = menuaccess.Where(i => i.MenuURL == menuUrl); // return menuaccess items matching given menuurl
    var mathingMenuUrlAndRolesMenuAccessCollection = mathingMenuUrlMenuAccessCollection.Where(i => currentUserRoles.Contains(i.RoleId)); // return menuaccess items matching roles in currentUserRoles
    var filteredMenuAccessCollection = mathingMenuUrlAndRolesMenuAccessCollection.Where(i => i.UserId == userid); // return menuaccess items matching given userid
    // FirstOrDefault will return the first menuaccess item from filteredMenuAccessCollection
    var checkControllerActionRoleUserId = filteredMenuAccessCollection.FirstOrDefault();
    

    总而言之,必须满足所有3个条件才能从menuaccess集合中获取项目,否则将返回null 。条件评估的顺序为

    To summarize, All 3 condition have to be satisfied to get item from menuaccess collection otherwise null will be returning. The order of conditions evaluation is


    • 首先,它尝试从menuaccess集合中找到匹配的menuUrl项。

    • 然后尝试找到在currentUserRoles集合中包含RoleId的menuaccess项。

    • 然后尝试从menuaccess集合中查找匹配的用户ID项。

    如果有多个满足以上3个条件的menuaccess项,则由于我们正在使用FirstOrDefault,它将从menuaccess集合中返回First项目。

    If there are multiple menuaccess items meeting the above 3 conditions then it will return the First item from the menuaccess colletion since we are using FirstOrDefault.

    更新:OnActionExecuting的简化版本:

    Update: Simplified version of OnActionExecuting:

    protected override void OnActionExecuting(ActionExecutingContext context)
    {
        base.OnActionExecuting(context);
        try
        {
            //int roleid = int.Parse(Env.GetUserInfo("roleid"));
            //int userid = int.Parse(Env.GetUserInfo("userid"));
            string userid = User.Identity.GetUserId();
            //string userid = Env.GetUserInfo("userid");
            //string roleid = Env.GetUserInfo("roleid");
            var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            // Select will return collection as opposed to scalar/single value. Pay attention to datatype here. 
            IEnumerable<string> currentUserRoles = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId);
            //string roleid = roles;
            // @Sam: Added this variable
            var actionNamesToCompare = new List<string>{"add", "index", "create", "edit", "delete", "multiviewindex"};
            var descriptor = context.ActionDescriptor;
            var actionName = descriptor.ActionName.ToLower();
            var controllerName = descriptor.ControllerDescriptor.ControllerName.ToLower();
            var controller = descriptor.ControllerDescriptor.ControllerName;
    
            var GetOrPost = context.HttpContext.Request.HttpMethod.ToString();
            var checkAreaName = context.HttpContext.Request.RequestContext.RouteData.DataTokens["area"];
            string AreaName = "";
            if (checkAreaName != null)
            {
                AreaName = checkAreaName.ToString().ToLower() + "/";
            }
    
            var cacheItemKey = "AllMenuBar";
    
            var global = HttpRuntime.Cache.Get(cacheItemKey);
    
            if (GetOrPost == "POST")
            {
                // Added index to string 02/03/2020
                // Added add to actonName settings 02/08/2020
                ///if menupermission create,edit,delete then update value "true" in IsMenuChange file
                if (controllerName == "menupermission" && actionNamesToCompare.Contains(actionName))
                {
                    global = MenuBarCache(cacheItemKey, global, "shortcache");
                }
            }
    
            if (global == null)//if cashe is null
            {
                global = MenuBarCache(cacheItemKey, global, "60mincache");//make cache from db
            }
    
    
            var menuaccess = (MenuOfRole[])global;
    
            if (GetOrPost == "GET")
            {
                if (actionNamesToCompare.Contains(actionName))
                {
                    // Old Impementation May be removed at Cleanup if not used - 02/10/2020
                    //ViewBag.Add = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsAdd));
                    //ViewBag.Read = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsRead));
                    //ViewBag.Create = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsCreate));
                    //ViewBag.Edit = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsUpdate));
                    //ViewBag.Delete = menuaccess.Where(i => i.MenuURL == controllerName).Select(i => (i.IsDelete))();
    
                    // Stack Overflow corrections - 02/10/2020
                    ViewBag.Add = menuaccess.Any(i => i.MenuURL == controllerName && i.IsAdd);
                    ViewBag.Read = menuaccess.Any(i => i.MenuURL == controllerName && i.IsRead);
                    ViewBag.Create = menuaccess.Any(i => i.MenuURL == controllerName && i.IsCreate);                        
                    ViewBag.Edit = menuaccess.Any(i => i.MenuURL == controllerName && i.IsUpdate);
                    ViewBag.Delete = menuaccess.Any(i => i.MenuURL == controllerName && i.IsDelete);
                    ViewBag.Visable = menuaccess.Any(i => i.MenuURL == controllerName && i.IsVisable);
                }
            }
    
            // @sam: you can combine menuUrl evaluation like this using ternary operator.
            var menuUrl = IsActionNameEqualToCrudPageName(actionName) ? AreaName + controllerName
                          : AreaName + controllerName + "/" + actionName;
    
            // var checkUrl = menuaccess.FirstOrDefault(i => (i.MenuURL == AreaName + controllerName + "/" + actionName) || i.MenuURL == menuUrl);
    
            // @sam: No need of this if statement
            // var checkUrl = menuaccess.FirstOrDefault(i => (i.MenuURL == AreaName + controllerName + "/" + actionName) || i.MenuURL == menuUrl);
            ///checkUrl: check if menu url Exists in MenuPermission if not exists then will be run
            /*if (checkUrl != null)
            {
                // Changed below line to use string instead of int..  01/26/2020
                //var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && String.IsNullOrEmpty(i.RoleId = roleid) && String.IsNullOrEmpty(i.UserId = userid));
                // Added change to use roles as collection.
                // @Sam: Since both if and else are doing same of operations, 
                //       the below if-else can be comibined as follows:
    
                /*var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl  &&currentUserRoles.Contains(i.RoleId) && i.UserId == userid);
                ///check menu  && roleid && userid
                if (checkControllerActionRoleUserId != null)
                {
                    if (IsActionNameEqualToCrudPageName(actionName))
                    {
                        CheckAccessOfPageAction(context, actionName, checkControllerActionRoleUserId);
                    }
                    else
                    {
                    if (checkControllerActionRoleUserId.IsRead == false || checkControllerActionRoleUserId.IsDelete == false || checkControllerActionRoleUserId.IsCreate == false || checkControllerActionRoleUserId.IsUpdate == false)//if userid !=null && Check Crud
                        {
                            UnAuthoRedirect(context);
    
                        }
                    }
                }
                else
                {
                    var checkControllerActionRole = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl && currentUserRoles.Contains(i.RoleId) && i.UserId == null);
                    if (checkControllerActionRole != null)
                    {
    
                        if (IsActionNameEqualToCrudPageName(actionName))
                        {
                            CheckAccessOfPageAction(context, actionName, checkControllerActionRole);
                        }
                        else
                        {
                            if (checkControllerActionRole.IsRead == false || checkControllerActionRole.IsDelete == false || checkControllerActionRole.IsCreate == false || checkControllerActionRole.IsUpdate == false)//if userid !=null && Check Crud
                            {
                                UnAuthoRedirect(context);
                            }
                        }
                    }
                    else
                    {
                        if (IsThisAjaxRequest() == false)//if userid !=null && Check Crud
                        {
                            UnAuthoRedirect(context);
                        }
    
                    }
                }//
            } */
            var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl  &&currentUserRoles.Contains(i.RoleId) 
             && (i.UserId == userid || i.UserId == null) // @Sam: This is how we can combine
             );
            ///check menu  && roleid && userid
            if (checkControllerActionRoleUserId != null)
            {
                if (IsActionNameEqualToCrudPageName(actionName))
                {
                    CheckAccessOfPageAction(context, actionName, checkControllerActionRoleUserId);
                }
                else
                {
                if (checkControllerActionRoleUserId.IsRead == false || checkControllerActionRoleUserId.IsDelete == false || checkControllerActionRoleUserId.IsCreate == false || checkControllerActionRoleUserId.IsUpdate == false)//if userid !=null && Check Crud
                    {
                        UnAuthoRedirect(context);
    
                    }
                }
            }
        }
        catch (Exception)
        { }
    }
    

    您可以为不同的用户测试数据。

    You can test with your data for different users.

    这篇关于获取AspNet用户RoleId以进行比较权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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