ASP.NET MVC авторизация и разрешение на использование моделей классов - PullRequest
5 голосов
/ 20 мая 2010

Это мой первый пост здесь, так что привет :) Хорошо, давайте перейдем к делу ... Я пишу свое первое приложение в ASP.NET MVC Framework, и у меня проблема с проверкой привилегий для использования экземпляров классов модели (чтение, редактирование). Пример кода выглядит так:

// Controller action

[CustomAuthorize(Roles="Editor, Admin")]
public ActionResult Stats(int id)
{
    User user = userRepository.GetUser(id);

    if (user == null || !user.Activated || user.Removed)
        return View("NotFound");
    else if (!user.IsCurrentSessionUserOwned)
        return View("NotAuthorized");

    return View(user);
}

Пока что атрибут authorize защищает только действия контроллера, поэтому мой вопрос: как сделать атрибут CustomAuthorize, чтобы проверять не только роль пользователя, имена пользователей, но также и ресурсы, т. Е. Ресурсы, созданные в методах действия (см. Выше: класс пользователя, но есть и другие ORM) Классы LINQ2SQL, такие как «Новости», «Фотографии» и т. Д.) Все эти проверяемые объекты имеют свои уникальные идентификаторы, поэтому у сущности пользователя есть собственный идентификатор, у «Новостей» - свои идентификаторы и поля «Идентификатор пользователя», связанные с таблицей «Пользователи». Как мне решить эту проблему?

1 Ответ

1 голос
/ 21 мая 2010

Если я правильно понимаю, вы хотите, чтобы пользователь, который пишет Новости, Статьи, мог редактировать свои собственные Новости или Статьи, даже если у него нет роли "Администратор" или "Редактор" ..

Ну, это сложно, простое решение будет:

Пусть ваш CustomAuthorize как есть, НО пусть он продолжит действие, вместо того, чтобы возвращать вид ошибки или что-то просто ввести параметр действия, то есть:

CustomAuthorize:

//..Your Role Validation Logic Here...
  if (filterContext.ActionParameters.Keys.Contains("isAuthorize"))
       {
         filterContext.ActionParameters.Remove("isAuthorize");
       }
   filterContext.ActionParameters.Add("isAuthorize", isAuthorized);

Где isAuthorized будет содержать результат логики проверки роли.

Итак, в вашем контроллере вы должны добавить второй параметр:

[CustomAuthorize(Roles="Editor, Admin")]
public ActionResult Stats(int id, bool isAuthorized)
{
    User user = userRepository.GetUser(id);

    if (user == null || !user.Activated || user.Removed)
        return View("NotFound");
    else if (user.Id != CurrentUser.Id && !isAuthorized)
            //not Authorized by roles
            //not the owner get away from here =D
        return View("NotAuthorized");

    return View(user);
}

Я предполагаю, что у вас есть доступ к CurrentUser, который поступает из свойства в BaseController (класс abstrac).

Реализация чего-то более сложного, чем это, приведет к сложной ситуации.

Например, вы можете, но не рекомендуется:

A. Отправьте ID пользователя владельца в качестве параметра (поэтому каждый раз, когда вы отправляете идентификатор по запросу GET или POST URL, вы должны добавить идентификатор пользователя владельца в качестве параметра). Но это может привести к действительно ужасным недостаткам безопасности, потому что вы зависите от идентификатора пользователя, отправляемого по проводу, который может быть подделан пользователем, и woala! я авторизован сейчас.

B. Попробуйте создать экземпляр объекта в фильтре действий (но сначала вы должны выяснить, какую сущность вы пытаетесь создать, это может привести к длинному оператору switch и третьему параметру в CustomAuthorize, чтобы вы знали, какую сущность получить из БД) .

...