Возможно, я упустил это где-то в «документации» по ASP.NET Identity (2.2.1), но я изо всех сил пытаюсь понять смысл создания контроллера и интерфейсов для управления ролями. Я понимаю смысл управления пользователями (CRUD + Назначение ролей), но CRUD для ролей просто не имеет для меня смысла, если нет способа динамически обнаруживать доступ (IsInRole) для контроллера во время выполнения. У меня два вопроса:

1] Есть ли смысл в выделении ресурсов и времени для создания CRUD для ролей, когда вам нужно сначала настроить приложение в коде, чтобы установить атрибут Authorize, чтобы даже установить роль, которая должна иметь доступ ?

А также

2] Есть ли способ зафиксировать момент, когда пользователь запрашивает действие у контроллера или даже у экземпляра контроллера, чтобы, возможно, проверить разрешения в этой точке из БД?

2
clockwiseq 25 Апр 2016 в 20:53

2 ответа

Лучший ответ

Лучший ответ, который я смог найти на SO, таков:

Динамически добавлять роли для авторизации атрибута для контроллера

Это именно то, чего я пытаюсь достичь, что оправдывает мой план создания CRUD для ролей. На этом этапе, поскольку я могу динамически добавлять роли к контроллеру с помощью описанного выше метода, я могу динамически создать роль, а затем включить ее в требование к контроллеру для ограничения доступа.

1
Community 23 Май 2017 в 11:59
  1. Я считаю роли очень полезными. Вместо того, чтобы украшать каждый контроллер, я помещаю ролевые украшения в абстрактные классы, которые я определяю для каждого раздела сайта. Затем каждый контроллер, используемый в разделе, наследуется от абстрактного класса этого раздела.

  2. Вы можете сделать это с помощью Http-модуля и переопределить событие AuthorizeRequest. Но я не думаю, что выполнение запроса к БД по каждому запросу было бы хорошей идеей. Роли существуют в памяти, поэтому авторизация ролей будет чрезвычайно эффективной.

РЕДАКТИРОВАТЬ:
Согласно вашим комментариям, вы можете создать для этого настраиваемый атрибут. Ниже я представляю, как это можно сделать. В событии OnAuthorization я бы создал блок if для каждой роли. Если пользователь является членом этой роли, проверьте, имеет ли эта роль доступ к текущему контроллеру. Пример демонстрирует эту идею только для одной роли с именем Admin.

using System.Web.Mvc;
using System.Security.Claims;

namespace MyApp.Filters
{
    public class CustomAttribute : AuthorizeAttribute
    {
        private List<string> adminControllers;

        public CustomAttribute()
        {
            this.adminControllers = new List<string>();

            //This would be a DB call
            this.adminControllers.Add("MyApp.Controllers.AccountController");
            this.adminControllers.Add("MyApp.Controllers.AdministrationController");
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            //Get the roles for the current user
            var identity = (ClaimsIdentity)filterContext.HttpContext.User.Identity;
            var roles = identity.Claims.Where(c => c.Type == ClaimTypes.Role)
                        .Select(c => c.Value).ToList();

            //Check if current user has the Admin role
            if (roles.Contains("Admin"))
            {
                //Check if Admin role has access to current controller
                if (this.adminControllers.Contains(filterContext.Controller.ToString()))
                {
                    filterContext.Result = new RedirectResult("~/Home/Error");
                }
            }


        }
    }
}
0
Clint B 26 Апр 2016 в 12:52