Главная страница   /   8.1. Аутентификация и авторизация (ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

Джеффри Палермо

8.1. Аутентификация и авторизация

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

Аутентификация подтверждает, что пользователь предоставил корректные данные для доступа в систему. Когда пользователь входит в систему (как правило, с помощью имени пользователя (логина) и пароля, но возможны и некоторые другие маркеры, такие как ключ SSH или зашифрованный ключ), он аутентифицирован.

Авторизация происходит после аутентификации и подразумевает принятие решения о том, имеет ли данный пользователь разрешение сделать что-либо в системе, например, просмотреть страницу или отредактировать запись. Если пользователь получает доступ к ресурсу, который не доступен для других, то он был специально авторизирован для этого.

Ограничение доступа с AuthorizeAttribute

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

По умолчанию новые проекты ASP.NET MVC, созданные на основе шаблона проектов Internet Application, для включения аутентификации используют схему forms-аутентификации, которая определена в разделе system.web/authentication в файле web.config:

<authentication mode="Forms">
	<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>

Когда включена forms-аутентификация и пользователь пытается получить доступ к закрытому ресурсу, он будет перенаправлен на LoginUrl для того, чтобы ввести имя пользователя и пароль.

Windows-аутентификация

В качестве альтернативы forms-аутентификации ASP.NET также поддерживает Windows-аутентификацию, которую можно включить, изменив <authentication mode="Forms"> на <authentication mode="Windows"> в web.config.

Windows-аутентификация попытается выполнить проверку пользователя с помощью учетной записи Windows с данными пользователя, и это лучше всего подходит для интранет-приложений, где пользователь входит в систему на том же домене, где находится приложение. На самом деле, эта схема аутентификации используется по умолчанию для шаблона проекта Intranet Application в ASP.NET MVC.

Когда аутентификация включена, мы можем применить AuthorizeAttribute к действиям контроллера (или даже целым контроллерам), чтобы ограничить доступ к ним. Если пользователь не имеет доступа к действию, AuthorizeAttribute передаст в браузер код статуса HTTP 401 Unauthorized, который указывает, что запрос был отклонен. Приложения, в которых используется forms-аутентификация, будут перенаправлять браузер на страницу входа, и пользователи смогут продолжить, только если выполнят вход.

Простейшее применение AuthorizeAttribute требует только аутентификации текущего пользователя:

[Authorize]
public ActionResult About()
{
	return View();
}

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

Чтобы ограничить действие далее, мы можем указать пользователей или роли, которые требует AuthorizeAttribute. Эти пользователи или роли передаются в атрибут в виде списка строк, разделенных запятыми и содержащих имена пользователей или ролей с правами доступа:

[Authorize(Users = "admin")]
public ActionResult Admins()
{
	return View();
}

В этом случае только пользователь с именем "admin" будет иметь доступ к данному действию.

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

[Authorize(Roles = "admins, developers")]
public ActionResult Developers()
{
	return View();
}

Доступ к действию Developers будет разрешен только для пользователей в роли администратора или разработчика - для всех других пользователей (аутентифицированных или нет) будет выдан код ответа 401 и, с помощью forms-аутентификации ASP.NET, они будут перенаправлены на страницу входа.

Аутентификация на основе ролей

Аутентификация на основе ролей может потребовать некоторых дополнительных настроек, в зависимости от схемы аутентификации, которую вы используете.

Если вы используете Windows-аутентификацию, роли будут автоматически найдены в групповом членстве Active Directory. Однако если вы используете forms-аутентификацию, вам нужно будет использовать провайдер членства (который может быть настроен в web.config), чтобы определить, где нужно сохранять и находить информацию о пользователях (например, роли).

Шаблон проектов для ASP.NET MVC Intranet Application по умолчанию будет использовать базу данных SQL Express для хранения ролей.

Теперь, когда вы видели несколько примеров использования AuthorizeAttribute, давайте поговорим о том, как он работает.

AuthorizeAttribute - как он работает

Внутренне AuthorizeAttribute реализован в виде IAuthorizationFilter, который выполняет несколько проверок, чтобы решить, имеет ли пользователь право доступа к текущему действию контроллера. Процесс принятия решений данного атрибута показан на рисунке 8-1.

Рисунок 8-1: AuthorizeAttribute проверяет, аутентифицирован ли пользователь, есть ли имя пользователя в белом списке и какова его роль, прежде чем принять решение, имеет ли пользователь права для просмотра требуемого действия

Поскольку AuthorizeAttribute реализует интерфейс IAuthorizationFilter, он должен содержать метод под названием OnAuthorization, который получает ссылку на AuthorizationContext, представляющий текущий запрос.

Когда фреймворк вызывает этот метод, атрибут получает ссылку на текущий IPrincipal, который соответствует пользователю, выполняющему текущий запрос. Если пользователь еще не прошел аутентификацию, он отменяет запрос, установив значение свойства Result класса AuthorizationContext на HttpUnauthorizedResult. Это отменяет вызов действия контроллера и отправляет в браузер код HTTP 401, который, в свою очередь, вызывает соответствующий запрос входа.

Если указаны пользователи или роли, AuthorizeAttribute проверяет, находится ли текущее имя пользователя в списке разрешенных имен, или приписана ли пользователю роль с правом доступа. Если же Users или Roles не указаны, пользователь получает права доступа.

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

AuthorizeAttribute можно использовать несколькими способами:

  • Если AuthorizeAttribute применяется к контроллеру, он применяется к каждому действию этого контроллера
  • Если несколько AuthorizeAttribute применяются к действию, пользователь должен пройти все проверки и быть авторизированным каждым из них

В ASP.NET MVC существует несколько других реализаций IAuthorizationFilter, и все они используются для защиты от нежелательных запросов.

В главе 16 фильтры будут описаны подробно, но давайте рассмотрим пять фильтров, которые связаны непосредственно с безопасностью:

  • AuthorizeAttribute: Об этом вы уже знаете
  • ChildActionOnlyAttribute: Гарантирует, что метод действия может быть вызван только из другого действия (обычно из представления с помощью Html.Action), но не может быть вызван напрямую
  • RequireHttpsAttribute: Гарантирует, что действие может быть доступно только через безопасное соединение
  • ValidateAntiForgeryTokenAttribute: Гарантирует, что был указан действительный маркер для борьбы с фальсификацией (вы узнаете об этом больше в следующем разделе)
  • ValidateInputAttribute: Указывает, должен ли ASP.NET проводить валидацию пользовательского ввода для обнаружения потенциально опасного содержимого

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