Литмир - Электронная Библиотека

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Index()

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Delete(Guid? userId)

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Select(Guid? userId)

Наоборот, действие Update вызывается только POST-запросами, поэтому пометим их следующим образом:

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Update(Guid? userId, string email,

  bool isApproved, bool isLockedOut);

Теперь, если мы попытаемся вызвать действие Update из строки запроса браузера, набрав URL вроде такого http://localhost:5434/Admin/Update, то получим ошибку с сообщением о том, что страница не была найдена. Без атрибута AcceptVerbs метод был бы вызван.

Для демонстрации действия атрибута NonActionAttribute проведем некоторые изменения в нашем коде. Обратите внимание на то, что в методах класса ActionController повторяется следующий код:

User.IsInRole("Administrators")

Вынесем его в отдельный метод UserlsAdmin:

[NonAction]

private bool UserIsAdmin()

{

  return User.IsInRole(''Administrators");

}

Обратите внимание, что мы пометили этот метод атрибутом NonAction, который указывает на то, что данный метод не является действием и не может быть выбран механизмом MVC при поиске в контроллере необходимого действия.

Атрибуты, производные от FilterAttribute

Когда механизм MVC находит необходимое для вызова действие, производится поиск и выполнение ряда атрибутов, которые являются производными от атрибута FilterAttribute. Такие атрибуты называются фильтрами и в основном предназначены для проверки прав вызова и безопасности контекста запроса. MVC Framework содержит ряд таких атрибутов, которые вы можете использовать в своих проектах:

□ AuthorizeAttribute — позволяет указывать ограничения для имен пользователей и ролей, которые могут вызвать данное действие;

□ HandleErrorAttribute — позволяет определять действия для обработки необработанных исключений;

□ ValidateAntiForgeryTokenAttribute — проверяет контекст запроса на соответствие указанному маркеру безопасности при получении данных из форм;

□ ValidateInputAttribute — управляет механизмом проверки запроса на небезопасные значения. Позволяет отключить такого рода проверку для случаев, когда требуется получить данные разного вида, в том числе потенциально опасные.

AuthorizeAttribute

AuthorizeAttribute — весьма полезный атрибут, который позволяет задавать группы и пользователей, имеющих доступ к заданному действию контроллера или ко всему контроллеру сразу. В нашем примере для проверки прав на доступ к действию контроллера AdminController мы создали следующий метод:

[NonAction]

private bool UserIsAdmin()

{

  return User.IsInRole("Administrators");

}

С использованием атрибута AuthorizeAttribute нужда в этом методе пропадает. Чтобы продемонстрировать действие AuthorizeAttribute, перепишем контроллер AdminController по-новому, так, как показано в листинге 4.3.

Листинг 4.3

public class AdminController : Controller

{

  [AcceptVerbs(HttpVerbs.Get)]

  [Authorize(Roles = "Administrators")]

  public ActionResult Index()

  {

    MembershipProvider mp = Membership.Provider;

    int userCount;

    var users = mp.GetAllUsers(0, Int32.MaxValue, out userCount);

    ViewData.Model = users;

    return View () ;

  }

  [AcceptVerbs(HttpVerbs.Post)]

  [Authorize(Roles = "Administrators")]

  public ActionResult Select(Guid? userId)

  {

    if (!userId.HasValue)

      throw new HttpException(404, "Пользователь не найден");

    MembershipProvider mp = Membership.Provider;

    MembershipUser user = mp.GetUser(userId, false);

    ViewData.Model = user;

    return View () ;

  }

  [AcceptVerbs(HttpVerbs.Post)]

  [Authorize(Roles = "Administrators")]

  public ActionResult Update(Guid? userId, string email,

                        bool isApproved, bool isLockedOut)

  {

    if (!userId.HasValue)

      throw new HttpException(404, "Пользователь не найден");

    MembershipProvider mp = Membership.Provider;

    MembershipUser user = mp.GetUser(userId, false);

    user.Email = email; user.IsApproved = isApproved;

    if (user.IsLockedOut && !isLockedOut)

      user.UnlockUser();

    mp.UpdateUser(user);

    return RedirectToAction("Index");

  }

  [AcceptVerbs(HttpVerbs.Get)]

  [Authorize(Roles = "Administrators")]

  public ActionResult Delete(Guid? userId)

  {

    if (!userId.HasValue)

      throw new HttpException(404, "Пользователь не найден");

    MembershipProvider mp = Membership.Provider;

    MembershipUser user = mp.GetUser(userId, false);

    mp.DeleteUser(user.UserName, true);

    return RedirectToAction("Index");

  }

}

Как вы можете заметить, мы избавились от рутинной операции проверки права доступа к действию контроллера путем задания для каждого действия атрибута [Authorize(Roles = "Administrators")]. Этот атрибут предписывает механизму MVC выполнить проверку права доступа пользователя при попытке вызвать действие нашего контроллера. Важным достоинством данного атрибута является его элегантность и унификация. Вместо того чтобы самим писать такой важный код, как код проверки прав доступа, мы оперируем механизмом метаданных в виде атрибута AuthorizeAttribute, помечая нужные нам участки кода. Так снижается возможность ошибки программиста, которая в случае работы с задачей безопасности может стоить очень дорого. Другим плюсом использования атрибута AuthorizeAttribute является заметное уменьшение кода, особенно в сложных вариантах, когда требуется предоставить доступ набору групп и пользователей.

Атрибут AutorizeAttibute принимает два параметра:

□ Roles — позволяет задавать перечисление ролей, которые имеют доступ к действию, через запятую;

□ Users — позволяет задавать перечисление пользователей, которые имеют доступ к действию, через запятую.

Так, например, следующий фрагмент кода определяет, что доступ к действию могут получить только члены группы Administrators и пользователи SuperUserl и SuperUser2:

[Authorize(Roles = "Administrators", Users = "SuperUserl, SuperUser2")]

HandleErrorAttibute

Атрибут HandleErrorAttribute предназначен для того, чтобы однообразно сформировать механизм обработки необработанных в контроллерах исключений. Атрибут HandleErrorAttribute применим как к классу контроллера, так и к любому действию. Кроме того, допустимо указывать атрибут несколько раз. По умолчанию, без параметров, механизм MVC с помощью атрибута HandleErrorAttribute при возникновении исключения произведет переадресацию на представление Error, которое должно находиться в папке -/Views/Shared. Однако это действие можно изменить под свои потребности. Для манипулирования порядком действия атрибута HandleErrorAttribute у него есть ряд параметров:

23
{"b":"971383","o":1}