BroadNet
HTTP API & webhooksБезопасность

Аутентификация API и подпись запросов: токены, HMAC, OAuth, mTLS

Обновлено 5 мин чтенияна основе стандартов
Прямой ответ

HTTP API аутентифицируют вызывающих учётными данными в заголовке Authorization — API-ключом или bearer token (Authorization: Bearer <token>). Более сильные схемы подписывают каждый запрос через HMAC над каноническим запросом, чтобы учётные данные никогда не были воспроизводимыми, используют OAuth 2.0 client-credentials для токенов machine-to-machine и добавляют взаимный TLS там, где нужна идентичность на транспортном уровне.

§01

Bearer token и API-ключи

Простейшая аутентификация — учётные данные bearer: клиент предъявляет секретный токен в заголовке Authorization, а сервер его проверяет. RFC 9110 определяет заголовок Authorization и префикс его схемы, а OAuth 2.0 определяет схему Bearer — Authorization: Bearer <token> — определяющее свойство которой в том, что доступ даёт само обладание, поэтому токен должен ходить только поверх TLS и никогда не появляться в URL, журнале или сообщении об ошибке. API-ключ — та же идея с более долгоживущим, часто бессрочным секретом. Поскольку учётные данные bearer воспроизводимы при захвате, это базовый уровень, а не потолок: их легко интегрировать, и поверх TLS они вполне достаточны для большей части трафика, но операции высокой ценности часто накладывают сверху подпись запросов.

Bearer token в запросеhttp
POST /v1/messages HTTP/1.1
Host: api.example
Authorization: Bearer eyJhbGciOi...  # secret; TLS only, never logged
Content-Type: application/json
§02

Подпись запросов через HMAC

Подпись запросов поднимает планку: вместо отправки секрета клиент использует его для вычисления HMAC над каноническим представлением запроса и отправляет только подпись. Сервер, держа тот же секрет, заново вычисляет подпись и сравнивает. Поскольку подпись покрывает метод, путь, ключевые заголовки и хеш тела, захваченную подпись нельзя воспроизвести против другого запроса, а поскольку сам секрет никогда не покидает клиента, захват одного запроса не раскрывает учётные данные. Конструкция зеркалит подпись webhook в обратном направлении и использует тот же примитив HMAC-SHA256 (RFC 2104 / RFC 6234). Тонкая часть — канонический запрос: обе стороны должны согласиться байт в байт о том, как его сериализовать, иначе каждая подпись не совпадёт.

Канонический запрос и подписьtext
canonical =
  HTTP-METHOD  + '\n' +
  URI-PATH     + '\n' +
  SORTED-QUERY + '\n' +
  SIGNED-HEADERS (name:value, sorted, '\n'-joined) + '\n' +
  HEX(SHA256(raw_body))

signature = HMAC_SHA256(secret, canonical)

Authorization: SIGV1 Credential=<key-id>,
  SignedHeaders=host;x-date;content-type, Signature=<hex>
§03

Подписанные заголовки и дата запроса

Две детали делают подпись запросов надёжной. Во-первых, явный список SignedHeaders называет ровно те заголовки, что покрыты, чтобы посредник, добавивший или переупорядочивший несвязанные заголовки, не аннулировал подпись, тогда как любой выбранный клиентом для подписи заголовок защищён от подделки. Во-вторых, дата запроса (подписанный X-Date или стандартный заголовок Date) является частью канонического запроса и сверяется с часами сервера в пределах допуска — та же защита от повторов, что у webhook, применённая к входящим вызовам API. Вместе они означают, что подписанный запрос привязан к своему точному содержимому, объявленным заголовкам и узкому окну времени; захваченный запрос бесполезен через несколько минут.

§04

Ограничение области и ротация ключей

Учётные данные должны нести наименьшую работающую привилегию и быть ротируемыми без простоя. Ограничение области привязывает разрешения к ключу — какие операции он может вызывать, из какого источника, с какой скоростью, — чтобы ключ, который только отправляет сообщения, не мог читать настройки аккаунта, а радиус поражения утёкшего ключа был ограничен. Ротация следует паттерну перекрывающихся ключей: выдать новые учётные данные, запустить оба параллельно, пока клиенты мигрируют, затем отозвать старые, чтобы ничего не сломалось на лету. Ключи должны быть идентифицируемыми (несекретный key id ходит в запросе, чтобы сервер знал, против какого секрета проверять и какую область применять) и отзываемыми по отдельности, чтобы одна скомпрометированная интеграция была отсечена, не нарушив остальные.

Сравнение схем аутентификации
СхемаЧто передаётсяМощность / использование
Ключ APIДолгоживущий секрет в AuthorizationПростой базовый вариант; только TLS; легко утекает в логи
Токен Bearer (OAuth 2.0)Кратковременный токен доступаС ограниченным сроком действия и областью; обновляется через token endpoint
Подпись запросов HMACПодпись (секрет остаётся локально)Устойчивость к повторному воспроизведению, обнаружение подделки для каждого запроса
mTLSСертификат клиента X.509Идентификация на транспортном уровне; надёжно, но сложнее в эксплуатации
§05

Взаимный TLS

Взаимный TLS аутентифицирует клиента на транспортном уровне: вдобавок к серверу, предъявляющему сертификат, клиент предъявляет собственный сертификат X.509 во время рукопожатия, а сервер допускает только соединения, чей сертификат выстраивается в цепочку к доверенному CA и совпадает с зарегистрированной идентичностью. Это привязывает идентичность API к криптографическому ключу, управляемому на уровне соединения, а не к секрету bearer в заголовке, что привлекательно для высоконадёжных связей machine-to-machine и для привязки партнёра к конкретным сертификатам. Цена — операционная: выпуск, распространение, ротация и отзыв сертификатов, — поэтому mTLS обычно резервируют для наиболее чувствительных интеграций, часто в сочетании с bearer token или подписью для тонкой авторизации поверх грубой транспортной идентичности.

§06

OAuth 2.0 client-credentials для M2M

Для интеграций сервер-сервер без присутствующего конечного пользователя OAuth 2.0 (RFC 6749) определяет грант client-credentials. Клиент аутентифицируется на token endpoint своими client_id и client_secret (или клиентским сертификатом) и получает короткоживущий access token, который затем предъявляет как bearer token в вызовах API, пока тот не истечёт и не будет обновлён. Преимущество перед статическим API-ключом — время жизни и область: токены короткоживущие, поэтому захваченный токен быстро истекает, и они несут явные области, поэтому токен, выпущенный для отправки, нельзя использовать для администрирования аккаунта. Это стандартный паттерн доступа к API machine-to-machine и механизм, который руководство по аутентификации BroadNet конкретно документирует для своих эндпоинтов.

Запрос токена OAuth 2.0 client-credentials (RFC 6749)http
POST /oauth/token HTTP/1.1
Host: auth.example
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=<id>
&client_secret=<secret>
&scope=messages:send

-> { "access_token": "...", "token_type": "Bearer",
     "expires_in": 3600, "scope": "messages:send" }
Часто задаваемые вопросы

Часто задаваемые вопросы

В чём разница между bearer token и подписью HMAC?

Bearer token отправляется в каждом запросе и даёт доступ обладанием, поэтому захваченный токен воспроизводим, пока не истечёт. Подпись HMAC никогда не отправляет секрет — клиент подписывает канонический запрос и отправляет только подпись, поэтому захваченный запрос нельзя воспроизвести против другого вызова, а сами учётные данные никогда не раскрываются.

Зачем подписи HMAC нужен канонический запрос?

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

Что даёт OAuth 2.0 client-credentials по сравнению с API-ключом?

Короткое время жизни и явную область. Клиент обменивает свои учётные данные на token endpoint на короткоживущий, ограниченный по области access token (RFC 6749). Захваченный токен быстро истекает, а токен, выпущенный для отправки, не может администрировать аккаунт. Статический API-ключ, напротив, долгоживущий и обычно широкий.

Как ограничивать область и ротировать API-ключи?

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

Когда взаимный TLS стоит операционных затрат?

Когда вам нужна криптографическая идентичность на транспортном уровне для высоконадёжной связи machine-to-machine или для привязки партнёра к конкретным сертификатам. mTLS допускает только клиентов, чей сертификат X.509 выстраивается в цепочку к доверенному CA. Его тяжелее эксплуатировать — выпуск, ротация, отзыв, — поэтому его обычно резервируют для наиболее чувствительных интеграций, часто накладывая токен или подпись для авторизации.

Почему учётные данные bearer никогда не должны попадать в URL или журнал?

Потому что учётные данные bearer дают доступ одним лишь обладанием. URL логируются прокси, хранятся в истории браузера и утекают через заголовок Referer, а журналы приложений широко читаемы, поэтому токен в любом из них фактически раскрыт. Учётные данные bearer должны ходить только в заголовке Authorization поверх TLS и вычищаться из журналов.

Ссылки

Технические характеристики источника

На этой странице представлены опубликованные стандарты, на которых они основаны. (Открывается в новой вкладке)

BNПоддерживается инженерной командой BroadNet·Обмен сообщениями операторского класса с 2003 года.
Прикрепите это к проводу

Разработано с использованием реального SMPP подключения и REST API.

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