Виды аутентификации в REST API

Виды аутентификации в REST API

ProQuality Community

Мы продолжаем серию статей про API. В предыдущих статьях мы узнали что такое API, какова структура запросов и ответов web API и какие методы и для чего используются в HTTP.

В сегодняшей статье мы поговорим об аутентификации.

Для начала давайте немного разберёмся в терминологии.

Идентификация — это заявление о том, кем вы являетесь. В зависимости от ситуации, это может быть имя, адрес электронной почты, номер учетной записи, и т.д.

Аутентификация — предоставление доказательств, что вы на самом деле есть тот, кем идентифицировались (от слова “authentic” — истинный, подлинный).

Авторизация — проверка, что вам разрешен доступ к запрашиваемому ресурсу.

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

В этой статье можно познакомиться со следующими видами аутентификации:

  • Базовая аутентификация (Basic access authentication)
  • Дайджест-аутентификация (Digest access authentication)
  • API ключи (API Keys)
  • Аутентификация на предъявителя (Bearer authentication, also called token authentication)

а также co стандартами взаимодействия при аутентификации с помощью токенов и форматы токенов.

Базовая аутентификация (Basic access authentication)

Наиболее простая схема, при которой username и password пользователя передаются в заголовке Authorization в незашифрованном виде, а в закодированном (base64-encoded).

Обратите внимание, что даже несмотря на то, что ваши учетные данные закодированы, они не зашифрованы! Получить имя пользователя и пароль при базовой аутентификации очень просто. Не используйте эту схему аутентификации на обычном HTTP, а только при использовании HTTPS (HTTP через SSL/TLS). Запрос при базовой аутентификации выглядит следующим образом:

GET / HTTP/1.1
Host: example.org
Authorization: Basic Zm9vOmJhcg==

В этом запросе закодированная пара username:password (Zm9vOmJhcg==) передаётся в заголовке Authorization.
Базовая аутентификация HTTP редко рекомендуется из-за присущих ей уязвимостей безопасности.

Дайджест-аутентификация (Digest access authentication)

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

При этой схеме сервер посылает уникальное значение nonce, а браузер передает MD5 хэш пароля пользователя, вычисленный с использованием указанного nonce.
Запрос клиента (без аутентификации)

GET /dir/index.html HTTP/1.0
Host: localhost

Ответ сервера

HTTP/1.0 401 Unauthorized
Server: HTTPd/0.9
Date: Sun, 10 Apr 2005 20:26:47 GMT
WWW-Authenticate: Digest realm="testrealm@host.com",
                       qop="auth,auth-int",
                       nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                       opaque="5ccc069c403ebaf9f0171e9517f40e41"
Content-Type: text/html
Content-Length: 311

Запрос клиента (имя пользователя «Mufasa», пароль «Circle Of Life»)

GET /dir/index.html HTTP/1.0
Host: localhost
Authorization: Digest username="Mufasa",
                    realm="testrealm@host.com",
                    nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                    uri="/dir/index.html",
                    qop=auth,
                    nc=00000001,
                    cnonce="0a4f113b",
                    response="6629fae49393a05397450978507c4ef1",
                    opaque="5ccc069c403ebaf9f0171e9517f40e41"

Ответ сервера

HTTP/1.0 200 OK
Server: HTTPd/0.9
Date: Sun, 10 Apr 2005 20:27:03 GMT
Content-Type: text/html
Content-Length: 7984

API ключи (API Keys)

Некоторые API используют API ключи для авторизации. API ключ – это длинная уникальная строка содержащая произвольный набор символов, по сути заменяющие собой комбинацию username/password.

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

GET /something?api_key=abcdef12345

или как заголовок

GET /something HTTP/1.1
X-API-Key: abcdef12345

или как cookie

GET /something HTTP/1.1
Cookie: X-API-KEY=abcdef12345

Хороший пример применения аутентификации по ключу — облако Amazon Web Services.

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

Bearer authentication (also called token authentication)

Аутентификация на предъявителя (также называемая аутентификацией токена) - это схема проверки подлинности HTTP, которая включает токены безопасности, называемые токенами на предъявителя. Имя «Аутентификация на предъявителя» можно понимать как «предоставить доступ носителю этого токена». Токен-носитель - это загадочная строка, обычно генерируемая сервером в ответ на запрос входа в систему. Клиент должен отправить этот токен несколькими способами:

в заголовке авторизации 

GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM

в теле запроса

POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
              access_token=mF_9.B5f-4.1JqM`

как параметр запроса

GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
Host: server.example.com

В случае некорректного запроса сервер в ответе присылает статус код (обычно 400, 401, 403 или 405) и текст ошибки. Пример ответа на запрос защищенного ресурса с попытка аутентификации с использованием просроченного токена доступа:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
                error="invalid_token",
                error_description="The access token expired"

В случае успешной авторизации ответ может выглядеть следующим образом:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
 {"access_token":"mF_9.B5f-4.1JqM",
  "token_type":"Bearer",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"}

Такой способ аутентификации чаще всего применяется при построении распределенных систем Single Sign-On (SSO), где одно приложение (service provider или relying party) делегирует функцию аутентификации пользователей другому приложению (identity provider или authentication service). Типичный пример этого способа — вход в приложение через учетную запись в социальных сетях. Здесь социальные сети являются сервисами аутентификации, а приложение доверяет функцию аутентификации пользователей социальным сетям. 

Реализация этого способа заключается в том, что identity provider (IP) предоставляет достоверные сведения о пользователе в виде токена, а service provider (SP) приложение использует этот токен для идентификации, аутентификации и авторизации пользователя.

Существует несколько стандартов определяющих протокол взаимодействия между клиентами и IP/SP-приложениями и формат поддерживаемых токенов. Среди наиболее популярных стандартов — OAuth, OpenID Connect, SAML, и WS-Federation.

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

При аутентификации с помощью токена SP-приложение должно выполнить следующие проверки:

  • токен был выдан доверенным identity provider приложением (проверка поля issuer).
  • токен предназначается текущему SP-приложению (проверка поля audience).
  • срок действия токена еще не истек (проверка поля expiration date).
  •  токен подлинный и не был изменен (проверка подписи).

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

Форматы токенов

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

  • Simple Web Token (SWT) - наиболее простой формат, представляющий собой набор произвольных пар имя/значение в формате кодирования HTML form.
  • JSON Web Token (JWT) – токен, основанный на формате JSON. Подробнее можно почитать на специальном ресурсе посвящённом данному формату токета.
  • Security Assertion Markup Language (SAML) - определяет токены (SAML assertions) в XML-формате, включающем информацию об эмитенте, о субъекте, необходимые условия для проверки токена, набор дополнительных утверждений (statements) о пользователе. Подробнее про этот стандарт можно почитать на официальном сайте

Стандарт OAuth

OAuth (Open Authorization)

Одной из проблем аутентификации и информационной безопасности является тот факт, что у одного пользователя, как правило, имеется несколько учётных записей на различных сервисах (например, на Google, Twitter, Apple и др.). При этом человеку приходится для каждого из сервисов иметь отдельные логин и пароль. В то же время, каждый из сервисов имеет свою систему безопасности, каждая из которых имеет свои уязвимости и недостатки. Как следствие, пользователям нужно хранить и защищать множество логинов-паролей, что вредит как удобству, так и безопасности; когда, например, пользователи для разных сервисов начинают использовать одни и те же пароли. В то же время, в данных обстоятельствах злоумышленникам становится проще осуществлять взлом (например, после получения доступа к одной из учётных записей взлом других может быть облегчён).

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

Стандарт OAuth (Open Authorization) не описывает протокол аутентификации пользователя, вместо этого он определяет механизм получения доступа одного приложения к другому от имени пользователя.

Первая версия стандарта разрабатывалась в 2007 – 2010 гг., а текущая версия 2.0 опубликована в 2012 г. Версия 2.0 значительно расширяет и в то же время упрощает стандарт, но обратно несовместима с версией 1.0. Несмотря на то, что стандарт OAuth 2.0 не утверждён, он используется некоторыми сервисами.

В чём отличия OAuth 2.0 от OAuth 1.0: 

  • добавлены функционал для лучшей поддержки приложений не основанных на браузере.
  • OAuth 2.0 больше не требует, чтобы клиентские приложения имели криптографию (это было настоящим испытанием для реализации) теперь это переносится на плечи протокола HTTPS.
  • OAuth 2.0 предназначен для четкого разделения ролей между сервером, отвечающим за обработку запросов OAuth, и сервером, который обрабатывает авторизацию пользователя.
  • подписи OAuth 2.0 менее сложны.
  • токены OAuth 2.0 не «долговечны». Как правило, токены доступа OAuth 1.0 могут храниться в течение года или более (Twitter никогда не дает им истечь). OAuth 2.0 имеет понятие токенов обновления.
    - токен доступа (access token): отправляется как ключ API, он позволяет приложению получать доступ к данным пользователя; опционально токены могут иметь срок действия.
    - токен обновления (refresh token): опциональная часть, токены обновления получают новый токен доступа, если срок их действия истек.

Стандарт OAuth2.0 описывает 4 вида грантов, которые определяют возможные сценарии применения:

  • Authorization Code — этот грант пользователь может получить от сервера авторизации после успешной аутентификации и подтверждения согласия на предоставление доступа. Такой способ наиболее часто используется в веб-приложениях. Этот процесс аналогичен тому, как пользователи регистрируются в веб-приложении, используя свою учетную запись Facebook или Google.
  •  Implicit — применяется, когда у приложения нет возможности безопасно получить токен от сервера авторизации (например, JavaScript-приложение в браузере). В этом случае грант представляет собой токен, полученный от сервера авторизации, а шаг № 2 исключается из сценария выше.
  •  Resource Owner Password Credentials — грант представляет собой пару username/password пользователя. Может применяться, если приложение является «интерфейсом» для сервера ресурсов (например, приложение — мобильный клиент для Gmail).

Client Credentials — в этом случае нет никакого пользователя, а приложение получает доступ к своим ресурсам при помощи своих ключей доступа (исключается шаг № 1).
Стандарт не определяет формат токена, который получает приложение: в сценариях, адресуемых стандартом, приложению нет необходимости анализировать токен, т. к. он лишь используется для получения доступа к ресурсам. Поэтому ни токен, ни грант сами по себе не могут быть использованы для аутентификации пользователя.

Подробнее познакомиться с OAuth можно в серии коротких видео 2 minutes OAuth.

Стандарт OpenID Connect

(Identity, Authentication) + OAuth 2.0 = OpenID Connect

OpenID Connect является средством аутентификации: с помощью этой системы можно удостовериться, что пользователь — именно тот, за кого себя выдаёт. Какие действия сможет совершать пользователь, прошедший аутентификацию посредством OpenID, определяется стороной, проводящей аутентификацию.

OpenID Connect предоставляет пользователю возможность создать единую учётную запись для аутентификации на множестве не связанных друг с другом интернет-ресурсов, используя услуги третьих лиц.

OpenID Connect позволяет клиентам всех типов (веб-клиенты, мобильные клиенты и клиенты JavaScript) запрашивать и получать информацию об аутентифицированных сеансах и конечных пользователях. Идентификационная информация пользователя закодирована в защищенном веб-токене JSON (JWT), который называется токеном идентификатора.

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

OpenID Connect определяет механизм обнаружения, называемый OpenID Connect Discovery, при котором сервер OpenID публикует свои метаданные по известному URL-адресу, например https://server.com/openid-configuration.

Этот URL-адрес возвращает JSON-список конечных точек OpenID / OAuth, поддерживаемых области и утверждения, открытые ключи, используемые для подписи токенов, и другие сведения. Клиенты могут использовать эту информацию для создания запроса к серверу OpenID. Имена и значения полей определены в спецификации OpenID Connect Discovery.

Подробнее о стандарте можно почитать на официальном ресурсе, а также можно посмотреть как работает OpenID в этом видео.

 

Источники материалов для статьи:

https://habr.com/ru/company/dataart/blog/262817/

https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml

https://blog.restcase.com/4-most-used-rest-api-authentication-methods/

https://www.wikipedia.org/

Report Page