Авторизация и защита веб-ресурсов в ASP.NET

Предоставление каждому посетителю сайта уникальной учётной записи позволяет вам однозначно идентифицировать любого из них. Идентификация позволяет веб-сайту менять оформление и контент в зависимости от предпочтений и интересов посетителей.

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

Корпоративные сайты, расположенные в защищённых внутренних сетях предприятий, могут содержать страницы с отчётами, предназначенными только для руководителей или сотрудников определённых отделов. Рядовые сотрудники не должны иметь доступа к этим ресурсам.

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

Например, в электронном магазине вы наверняка позволите каждому пользователю просматривать витрину и пользоваться корзиной заказов.

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

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

Рассмотрим, как организована авторизация в популярном веб-фреймворке ASP.NET.

Что такое авторизация?

Как мы уже говорили, предоставление пользователям уникальных учётных записей позволяет идентифицировать их. Механизм «узнавания» сайтом зарегистрированных посетителей называется аутентификацией.

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

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

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

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

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

Использование аутентификации и авторизации для защиты сайта, построенного на основе технологий ASP.NET – основная тема этой статьи.

Управление доступом на основе групп и ролей

Хотя права можно назначать индивидуально каждому пользователю сайта, управление этим процессом существенно осложняется по мере роста числа пользователей. Любое изменение в системе безопасности сайта может потребовать перенастройки прав большого количества пользователей, что требует времени и чревато ошибками.

Для решения этой проблемы пользователи, имеющие одинаковые права или потребности, собираются в группы. Отдельные права также могут явно или неявно группироваться в так называемые роли. Роли, в свою очередь, могут назначаться отдельным пользователям или группам. В некоторых системах «роль» и «группа» являются синонимами.

Новый пользователь на сайте включается в какую-либо группу. Это может делаться автоматически либо вручную, администратором сайта. Таким образом, пользователь получает заранее определённый набор прав и ограничений.

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

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

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

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

Хорошей практикой является разделение пользователей на группы по виду деятельности на сайте. Например, наш блог может иметь следующие группы пользователей: «Авторы», «Редакторы», «Модераторы» и т.д.

Альтернативный подход будет состоять в том, чтобы выделить группы «Создание статей», «Правка статей», «Удаление комментариев» и т. д. Такой подход будет обладать значительной гибкостью, но при этом придётся поддерживать на сайте большее количество различных групп.

Защита страниц средствами ASP.NET

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

При защите сайта на ASP.NET используются три направления разделения доступа:

  • Система роутинга адресов;
  • Веб-формы (файлы и папки);
  • Структуры MVC.

Защита сайта на веб-формах

Как веб-формы, так и роутинг в ASP.NET использует для защиты доступа web.config. Основа конфигурации для защиты доступа к ресурсам сайта выглядит примерно так:

<configuration>  
   <location path="adminhome.aspx">  
      <system.web>  
         <authorization>  
           <allow roles="admin"/>  
           <deny users="*"/>  
         </authorization>  
      </system.web>  
   </location>  
</configuration>

XML-элемент location определяет путь к защищаемому ресурсу: папке, странице или элементу роутинга. В данном примере он задаёт страницу adminhome.aspx. Можно защитить содержимое папки целиком, указав путь к ней. Если атрибут path отсутствует, настройки безопасности применяются к той папке, в которой находится файл web.config, со всеми её подпапками.

Элемент authorization определяет, кто имеет или не имеет доступа к защищаемому ресурсу. Права проверяются последовательно, начиная с первого и до тех пор, пока совпадение не будет найдено. Вложенный элемент allow задаёт разрешение, а deny – запрещение доступа к ресурсу для заданного пользователя или роли.

В нашем примере правило <allow admin role /> будет проверено первым. Если пользователь обладает ролью администратора, доступ ему будет предоставлен, и проверка условий на этом прекратится.

В противном случае проверка продолжится до следующего правила: <deny users="*" />, которое лишит доступа к ресурсу всех пользователей. Таким образом, наш пример даёт доступ к файлу только администраторам. Всем остальным будет отказано в доступе.

Существует несколько специальных символов, обозначающих часто используемые группы. Мы уже видели символ «*», обозначающий всех пользователей.

Символ «?» обозначает анонимного (не успевшего зарегистрироваться) пользователя. Несколько групп или отдельных пользователей могут быть перечислены через запятую. Пользователи и роли могут смешиваться в одном правиле, например:

<allow roles="siteadmin,editors" users="bob">

Защита MVC-сайта

Разработка сайта согласно методологии MVC сосредотачивается не на файлах и папках, а на контроллерах и их действиях. Соответствующим образом меняется и защита. По умолчанию все действия всех контроллеров доступны всем пользователям, как и в случае с веб-формами. Вам доступны те же пользователи и роли, но файлов web.config больше нет.

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

[Authorize(Roles = "siteadmin")]  
public class AdminController : Controller  
{
...

Для обозначения анонимов и всех пользователей доступны те же символы «?» и «*». Вы можете применять установки ко всему контроллеру или к отдельным действиям. При этом настройки действий будут иметь более высокий приоритет, чем настройки всего контроллера:

[Authorize(Roles = "siteadmin")]  
public ActionResult AdminView()  
{
...

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

В ASP.NET 4 был добавлен атрибут [AllowAnonymous], который позволил разрешить анонимному пользователю доступ к отдельным действиям защищённого контроллера.

Управление контентом в зависимости от роли

Ограничив доступ к страницам и контроллерам, следующим шагом вы должны убедиться в том, что доступ к самому серверному коду осуществляется правильно. Некоторые объекты легко защитить, потому что к ним должны иметь доступ только пользователи с определённой ролью, и доступ этот – полный.

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

Например, не имеет смысла показывать ссылку на панель администрирования рядовым пользователям. Клиент, не имеющий отправленных заказов, не должен видеть кнопку трекинга. Даже если элемент не активен или ведёт на страницу авторизации, он может смутить простого пользователя и дать злоумышленнику пищу для размышления.

Код, исполняемый сервером на странице, доступной нескольким ролям, должен всегда проверять права пользователя и основывать свои действия на результате этой проверки.

Если на странице, просматриваемой как обычными посетителями, так и администраторами, должна быть ссылка на ресурс, доступный только администратору, то в варианте, предназначенном для обычного пользователя, её нужно скрыть.

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

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

UpdateOrder.aspx?order=33&action=delete

Теперь, представьте хакера, удаляющего все заказы перебором параметра order. Проверяется ли принадлежность заказа пользователю в соответствующем обработчике?

В другом случае отсутствие проверки в чём-то вроде:

UpdateOrder.aspx?order=33&action=refund

позволит злоумышленнику получить возмещение за чужой или не оплаченный заказ. Никогда не полагайтесь на скрытие ссылок как единственный механизм защиты от не авторизованного доступа.

Аспекты безопасности пользовательских сессий

Защита самих данных авторизации является отдельной задачей безопасности, хоть и близко соотносящейся с безопасностью доступа к ресурсам и коду. Во-первых, на безопасность механизма аутентификации влияет продолжительность сессии. В ASP.NET этот параметр задаётся в web.config следующим образом:

<forms loginUrl="~/Auth/LogOn.aspx" timeout="30" slidingExpiration="true" />

В этом примере время жизни сессии составит 30 минут. Атрибут slidingExpiration определяет, сбрасывает ли счётчик истечения сессии поступление запроса от пользователя. Если установить данному атрибуту значение false, пользователю придётся осуществлять вход каждые 30 минут, даже во время активной работы с сайтом.

Также необходимо учитывать возможность кражи сессии. Большинство веб-фреймворков хранят идентификатор сессии в маленьком кусочке текстовых данных, называемом кукой или печенькой (cookie), в браузере пользователя.

Если кука никак не защищена, её может использовать злоумышленник, перехватив трафик легитимного пользователя и представившись системе этим пользователем.

Существуют средства вроде FireSheep – расширения для браузера Firefox – позволяющие демонстрировать редактирование или подмену авторизационной куки.

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

Фреймворк ASP.NET позволяет усилить защиту сайта, установив атрибут формы входа на сайт requireSSL=»true». Для ещё большей безопасности рекомендуется также применить тэг в конфигурации сайта.

Заключение

Использование одного и того же веб-сайта посетителями с разными потребностями и разным уровнем ответственности требует использования различных методов предотвращения несанкционированного доступа к данным и функциям. Вы можете идентифицировать пользователя и применить к нему нужные установки безопасности на вашем сайте.

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

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

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

Комбинация этих мер позволит вам создать безопасный и защищённый веб-сайт.

Перевод статьи «Authorization and Protecting Web Resources in ASP.NET» был подготовлен дружной командой проекта Сайтостроение от А до Я.