Хорошая практика, чтобы сделать общую авторизацию на фабрике пользовательских контроллеров?

Мои контроллеры имеют общий идентификатор клиента. Маршрут:

clients/{clientId}/{controller}/{action}/{id}

Примеры URL:

clients/1/orders/details/1
clients/2/children/index
clients/2/cars/create

Вам нужно правильное разрешение для клиента. Я не хочу делать одинаковую клиентскую авторизацию на каждом контроллере. Мне пришла в голову идея сделать авторизацию на фабрике пользовательских контроллеров следующим образом:

public class CustomControllerFactory : DefaultControllerFactory
{
    private readonly IAuthService _authService;

    public CustomControllerFactory(IAuthService authService)
    {
        _authService = authService;
    }

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    {
        var doAuth = requestContext.RouteData.Values.ContainsKey("clientId");
        if (doAuth)
        {
            var principal = requestContext.HttpContext.User;
            var clientId = long.Parse(
                requestContext.RouteData.Values["clientId"].ToString());
            var authorized = _authService.Client(principal, clientId);
            if (!authorized)
            {
                return new AuthController();
            }                
        }
        return base.GetControllerInstance(requestContext, controllerType);
    }
}

Вы считаете это хорошей практикой или нет? Зачем?

3 ответа

Нет, я не считаю это хорошей практикой. Пользовательский атрибут AuthorizeAttribute кажется гораздо более приспособленным для обработки авторизации, чем для фабрики контроллеров.

Мы уже использовали приведенную ниже концепцию для проверки авторизации;

Шаг 1: Необходимо создать 3 разные таблицы и ввести соответствующие данные;

A. Таблица: Действия

ID:int,PK Контроллер:varchar(100) Действие:varchar(100) Метод HTTP: varchar (10)

B. Таблица: разрешение

Id: int,PK Имя:varchar(100)

C. Таблица: Permission_Action

Id: int,PK PermissionId: int, FK ActionId: int, FK

Шаг 2. Создайте ApplicationController, который будет унаследован от класса "Controler", а все остальные контроллеры должны быть унаследованы от "ApplicationController" вместо "Controller".

//Declaration of ApplicationController
public class ApplicationController : Controller
//Declaration of Other controller
public class OtherController : ApplicationController 

Шаг 3: Для обеспечения устойчивости извлеките все контроллеры и действия для текущего пользователя после аутентификации. Кроме того, мы можем запускать SQL-запросы каждый раз.

Шаг 4: В методе "OnActionExecuting" у вас будет информация о контроллере и действии текущего запроса. Изучил список действий контроллера, полученный на шаге 3, чтобы узнать текущий контроллер и действие.

 string controller = filterContext.RouteData.Values["controller"] as string;
 string action = filterContext.RouteData.Values["action"] as string;
 string httpMethod = filterContext.HttpContext.Request.HttpMethod.ToLowerInvariant();

Шаг 5: Если найден, пользователь имеет право продолжить действие, в противном случае вернуть предопределенный "SecurityResult"

Пример:

ПРИМЕЧАНИЕ: действия, связанные с "Авторизацией", должны быть назначены во время создания пользователей. Эта часть исключена в этом примере;

A. Данные таблицы действий:

{1, "Сотрудник", "Деталь", "получить"},{2,"Сотрудник", "Создать", "получить"},{3,"Сотрудник", "Создать", "пост"},{4 "Сотрудник", "Удалить", "пост"}

B. Данные таблицы разрешений:

{1, "Просмотр сведений о сотруднике"},{2,"Создание сведений о сотруднике"},{3,"Удаление сведений о сотруднике"}

C. Данные таблицы Permission_Action:

{1, 1, 1}, {1, 2, 2}, {1, 2, 3}, {1, 3, 4}

D. Теперь у пользователя "vrluckyin" есть только разрешение на просмотр данных и создание сотрудника.

Действие "Удалить" из "Сотрудник" не назначено.

После авторизации, если пользователь "vrluckyin" пытается вызвать действие "delete" контроллера "Employee", система вернет представление безопасности вместо представления удаления.

  • Не нужно писать атрибут [Authorize] для каждого действия.
  • Мы можем легко добавлять / удалять / обновлять права пользователей. Изменения только базы данных!!!

Наслаждайтесь!

Это абсолютно лучшая практика, когда ваше приложение имеет очень сильную модель многопользовательского режима или владения пользователями.

[Authorize] атрибуты, даже на уровне класса, просто беспорядочные, если вы украшаете ими большинство приложений. [Authorize] атрибуты также могут быть забыты. Ваша техника всегда будет работать.

Другие вопросы по тегам