Аутентификация и авторизация
Одна из основных проблем безопасности заключается в подтверждении того, что только определенным пользователям разрешен доступ к системе. Здесь начинают действовать понятия аутентификации и авторизации.
Аутентификация подтверждает, что пользователь предоставил корректные данные для доступа в систему. Когда пользователь входит в систему (как правило, с помощью имени пользователя (логина) и пароля, но возможны и некоторые другие маркеры, такие как ключ 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
может помочь в управлении аутентификацией и авторизацией, так что давайте обратим наше внимание на другие, более коварные направления атак. Хотя аутентификация и авторизация и закрывают случайным посетителям доступ к защищенным областям, вы все еще должны защитить вашу программу от хакеров и воров, которые пытаются использовать уязвимости веб-приложений. Далее в этой главе мы рассмотрим несколько распространенных атак и уязвимостей и способы защиты от них.