1.7. Аутентификация и авторизация в веб-приложениях

 

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

Наверняка вы часто слышали такие слова, как аутентификация и авторизация. Что они означают и какая между ними разница?

Проще говоря, аутентификация должна отвечать на вопрос «Кто ты?».

Авторизация же отвечает на вопрос «Что ты можешь делать?».

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

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

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

Существует множество методов и протоколов аутентификации. В этой статье мы рассмотрим наиболее популярные:

  • HTTP аутентификация
  • На основе сертификатов
  • На основе HTML форм
  • Single Sign-On (SSO)

 

Базовая HTTP аутентификация

Базовая HTTP аутентификация (Basic authentication) определена самим протоколом HTTP, то есть является его «родным методом». Принцип работы проиллюстрирован на рисунке ниже:

Basic authentication в веб-приложениях

  1. Пользователь входит на сайт или в закрытую часть сайта, где нужно аутентифицироваться.
  2. Сервер отвечает кодом 401 Authorization Required и добавляет заголовок WWW-Authenticate. Заголовок содержит тип аутентификации (Basic) и поле Realm, которая представляет собой название закрытого раздела, к которому запрашивается доступ.
  3. Когда браузер получает такой ответ, то сразу всплывает простое окно в верхней части браузера для ввода данных аутентификации.
  4. После ввода логина и пароля браузера объединяет их в одну строку, разделяя при этом двоеточием, то есть так: login:password. А затем кодирует данную последовательность алгоритмом
  5. После этого браузер снова посылает такой же запрос, как и в шаге 1, однако в этом случае добавляет заголовок Authorization, в котором указывает закодированную последовательность.
  6. Сервер, приняв запрос, декодирует значение заголовка Authorization и извлекает логин и пароль. Если они совпадают в его базе данных, то в ответе 200 ОК отправляет запрашиваемый ресурс.

Механизм довольно простой, но не лишен своих недостатков:

  • Браузеру нужно постоянно передавать данные аутентификации с каждым запросом
  • Пароль в открытую передается по сети, а значит соединение по SSL/TLS просто необходимо.
  • Нет возможности «выйти» из приложения. Единственный выход – это ввести неверный пароль или логин.

 

Digest HTTP аутентификация

Чтобы повысить безопасность предыдущего метода механизм Basic Authentication был немного улучшен и получил название Digest Authentication. Его особенность в том, что пароль уже не передается по сети. Вместо него вычисляется уникальная последовательность, которая известна браузеру и серверу. Принцип работы показан ниже:

Digest authentication в веб-приложениях

  1. Пользователь входит на сайт или в закрытую часть сайта, где нужно аутентифицироваться.
  2. Сервер отвечает кодом 401 Authorization Required и добавляет заголовок WWW-Authenticate. Заголовок содержит тип аутентификации (Digest), поля Realm и другие данные.
  3. Когда пользователь вводит данные, то браузер снова объединяет их в одну строку и затем вычисляет хэш. В качестве хэш-функции обычно выступает MD
  4. Далее в заголовке Authorization передается вычисленный хэш и другая дополнительная информация.
  5. Сервер в свою очередь выполняет те же вычисления, и если оба значения хэш совпадают, то пользователь аутентифицирован.

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

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

Как видите пароль вообще не передается по сети, однако назвать данный метод самым безопасным тоже нельзя.

Basic authentication и Digest authentication в настоящее время практически не используются.

 

Сертификаты

При соединении через SSL/TSL браузеры проверяют сертификаты, установленные на веб-сайтах, чтобы аутентифицировать серверы (подробнее здесь). Подобные сертификаты можно устанавливать и на компьютерах, чтобы серверы могли аутентифицировать пользователей (точнее устройства), подключаемых к ним. Сервер в свою очередь содержит список сертификатов и пользователей, которые могут к нему подключаться.

Метод довольно надежный (хотя и сертификаты, и центры аутентификации тоже могут быть скомпрометированы), однако имеет существенные недостатки:

  • Достаточно сложно обеспечить большое количество пользователей необходимыми сертификатами. Поэтому данный метод используется в основном на правительственных сайтах и лишь для малого количества пользователей.
  • Сертификат устанавливается в устройстве (компьютер, ноутбук), а значит на сайт можно будет зайти только с определенного устройства. Можно установить и на флэшку, но это не всегда удобно.

 

Аутентификация на основе форм (Form-based authentication)

В основе данного метода лежит использование различных HTML форм, которые содержат поля для ввода логина и пароля. На рисунке ниже проиллюстрирован весь процесс:

Аутентификация на основе HTML форм и куки

 

Аутентификация на основе HTML форм и куки

  1. Пользователь запрашивает определенный ресурс на сайте, например хочет открыть секретный документ.
  2. Сервер перенаправляет его на страницу авторизации, которая и содержит HTML форму для ввода пользовательских данных.
  3. После ввода данных браузер отправляет их серверу через POST запрос, причем сами данные отправляются в теле запроса в качестве параметров в виде параметр_1=значение_1&параметр_2=значение_2. Сами параметры разделены амперсандом. Здесь проглядывается аналогия с Basic Authentication., так как и там и здесь используется форма, а сами данные передаются открытым текстом. Поэтому необходимо всегда использовать SSL/TLS подключение.
  4. На приеме сервер сверяет полученные данные с данными, которые хранятся в базе данных. В БД не рекомендуют хранить пароли в отрытом виде, так как БД может взломана и все пароли будут раскрыты. Поэтому вместо них хранятся хэши паролей.
  5. Если пароли или их хэши совпадают, то сервер генерирует новый сессионный идентификатор, которые передается через заголовок Set-Cookie. Обязательно устанавливаются атрибуты HttpOnly (чтобы Cookie не были доступны сторонним скриптам JavaScript), Secure (чтобы Cookie всегда передавались по SSL/TLS) и Expired (чтобы браузер и сервер автоматически удалили Cookie по истечении установленного срока).
  6. Браузер принимает Cookie и сохраняет их для последующей передачи серверу.
  7. Уже успешно авторизованный пользователь снова вводит запрос для доступа к секретному документу. Браузер автоматически добавляет Cookie к каждому запросу.
  8. Сервер проверяет и сверяет полученное значение Cookie и значение, сохраненное в своем хранилище или БД. Если все в порядке, то пользователю выдается запрашиваемый ресурс. Причем пользователю не нужно постоянно вводить пароль.
  9. Если пользователь желает выйти из системы, то направляет соответствующий запрос.
  10. Сервер удаляет текущее значение Cookie и генерирует новое значение, которое передает в заголовке Set-Cookie.
  11. Браузер, приняв новое значение Cookie, также удаляет старое значение и записывает новое.

Данный метод широко используется во многих веб-приложениях, однако он также не лишен недостатков, так как подвержен атакам Инъекция SQL (SQLi) и Перебор паролей (Brute force, Dictionary attack и так далее). Поэтому на стороне сервер необходимо тщательно проводить проверку и валидацию введенных данных. В принципе это касается всех веб-приложений и методов аутентификации, которые передают пользовательские данные и параметры.

 

Единый вход - Single Sign-On (SSO)

Single Sign-On (SSO) — это технология, позволяющая пользователям получать доступ к нескольким веб-приложениям с помощью одного набора учетных данных. Вместо того, чтобы вводить логин и пароль для каждого приложения отдельно, пользователь может войти в систему один раз и автоматически получить доступ ко всем своим приложениям. Например, наверняка вы часто встречали приложения, где предлагалось войти в систему с помощью аккаунта в Google или Facebook.

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

В процессе аутентификации/авторизации участвуют как минимум 3 стороны, поэтому для начала определимся с терминологией.

Service Provider (SP) или Client – это веб-приложение, которое запрашивает доступ к вашим данным или ресурсам. Например, это может быть Spotify, который для авторизации пользователя может запрашивать ресурсы из Google или Facebook:

Скриншот страницы авторизации через соц сети

Identity Provider (IdP) – это сервер авторизации, который хранит ваши учетные данные, а также ваши ресурсы. Это могут быть фотографии, документы, медиафайлы и так далее. В качестве IdP могут выступать Google, Facebook, VK и многие другие.

User-Agent – это, собственно говоря, сам пользователь. В различных источниках он может обозначаться как Client, User-Agent или просто браузер.

Принцип работы SSO проиллюстрирован ниже:

Процесс авторизации в Single Sign-On

  1. В начале SP и IdP устанавливают друг с другом доверительные отношения, проще говоря, SP регистрируется в IdP, чтобы использовать учетные данные его пользователей у себя на сайте.
  2. Затем пользователь обращается к Service Provider (пусть будет Spotify) для доступа к его услугам.
  3. Service Provider предлагает сначала авторизоваться, например в Google. Для этого он переадресовывает пользователя на страницу авторизации Google, при этом в URL запросе указывается свой собственный идентификатор, по которому Google его определит и многие другие параметры.
  4. Identity Provider, в нашем случае Google, предлагает пользователю ввести логин и пароль.
  5. После успешной авторизации IdP генерирует специальный токен, который содержит данные о сроке его действия, цифровую подпись и другие данные. Данный токен передается обратно к SP через браузер пользователя, используя запрос переадресации.
  6. Service Provider принимает токен, проверяет его цифровую подпись, чтобы убедиться, что он не поддельный и затем передает пользователю запрашиваемые ресурсы, например доступ к закрытой части сайта. При этом токен сохраняется в браузере пользователя и при последующих обращениях к Service Provider браузер передает ему токен через заголовок Cookie или в самом теле POST запроса.

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

Для реализации SSO применяют следующие протоколы:

  • OAuth 2.0
  • OpenID Connect (OIDC)
  • Security Assertion Markup Language (SAML)

Для реализации токенов используют следующие технологии:

  • Simple Web Token (SWT)
  • JSON Web Token (JWT)
  • Security Assertion Markup Language (SAML)

OAuth 2.0 и OpenID Connect обычно используются в связке, так как OAuth 2.0 используется только для авторизации, например IdP с разрешения пользователя предоставляет Service Provider право воспользоваться ресурсами пользователя. Это могут быть файлы, например фотографии, или список контактов. Сам пользователь в OAuth не аутентифицируется, поэтому поверх него реализуется протокол OIDC, который и отвечает за данную процедуру. В результате успешной аутентификации и авторизации IdP генерирует 2 токена: токен доступа (Access token) и токен идентификатора (ID token). Обычно для генерирования токена применят формат JSON Web Token (JWT).

SAML выполняет те же функции, что и OAuth и OIDC, то есть он обеспечивает аутентификацию и авторизацию, при этом он использует формат XML сообщений. В своей реализации он сложнее и к тому же не может использоваться в мобильных приложениях.