Получение как pNet пользователей RoleId для сравнения в разрешениях - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть область, где RoleId хранится в виде строки в таблице разрешений. Я делаю сравнение на Id, чтобы получить все разрешения для роли. Я получаю текущий зарегистрированный пользователь RoleId, как это.

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

Это не нравится использование строки. Я получаю

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

. Здесь я делаю сравнение. Обратите внимание, что разрешение может иметь либо UserId, либо RoleId. У меня нет проблем с UserId с этой настройкой.

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

Есть ли другой способ получить RoleId или, может быть, другое слово для сравнения?

Спасибо

Обновление: добавлен контроллер ниже. Извините, это долго ..

   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 предложил ниже, мне также нужно было найти способ не предоставлять доступ пользователям, которых нет в таблице разрешений. Чтобы избежать избыточности. Если у пользователя нет доступа к чему-либо, мне не нужно добавлять его в разрешения, чтобы убедиться, что у него нет доступа. Я добавил в раздел нижеприведенный код для перенаправления на панель инструментов, если пользователь попадает на страницу, к которой у него нет доступа.

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

1 Ответ

0 голосов
/ 11 февраля 2020

В вашем коде есть несколько проблем. После исправления текущей ошибки вы получите больше ошибок:

  1. Вы назначаете коллекцию строк в строку (через string roleid). В настоящее время вы получаете эту ошибку. После исправления этой ошибки появятся следующие ошибки:

Причина, по которой вы получаете ошибку, заключается в следующем:

  • Приведенный ниже оператор возвращает коллекцию ролей (collectionId collection если быть точным) зарегистрированного пользователя, а не одного идентификатора роли.

    string roleid = userManager.FindById(User.Identity.GetUserId()).Roles.Select(r => r.RoleId);`
    
  • И затем вы пытаетесь присвоить эту ролевую коллекцию скалярному свойству i .RoleId (через i.RoleId = roleid) в следующем операторе

    var checkControllerActionRoleUserId = menuaccess.FirstOrDefault(i => i.MenuURL == menuUrl &&  String.IsNullOrEmpty(i.RoleId = roleid) && String.IsNullOrEmpty(i.UserId = userid));`
    
  • Использование оператора присваивания = вместо == для сравнения. Итак, вы пытаетесь присвоить roleid i.RoleId, что недопустимо.

  • Использование оператора присваивания = вместо == для сравнения. Итак, вы пытаетесь назначить идентификатор пользователя для i.UserId, что недопустимо.

Исправление: Пожалуйста, измените раздел 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); 

(ИЛИ)

//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) . Я также исправил условие вокруг идентификатора пользователя.):

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

В качестве альтернативы, приведенное выше утверждение может быть разделить, используя Where и FirstOrDefault следующим образом:

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

Выше можно в дальнейшем переписать следующим образом:

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 будет возвращаться. Порядок оценки условий:

  • Сначала он пытается найти соответствующие элементы menuUrl из коллекции menuaccess.
  • Затем пытается найти элемент доступа к меню, где RoleId содержится в коллекции currentUserRoles.
  • Затем он пытается найти совпадающие элементы идентификатора пользователя из коллекции menuaccess.

Если имеется несколько элементов доступа к меню, удовлетворяющих вышеуказанным 3 условиям, он вернет первый элемент из коллекции menuaccess, так как мы используя FirstOrDefault.

Обновление : упрощенная версия 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)
    { }
}

Вы можете проверить свои данные для разных пользователей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...