JWT (Json Web Token) Аудитория «aud» против Client_Id - в чем разница?

104

Я работаю над внедрением OAuth 2.0 JWT access_token на моем сервере аутентификации. Но я не понимаю, в чем разница между audзаявлением JWT и client_idзначением заголовка HTTP. Они одинаковы? Если нет, можете ли вы объяснить разницу между ними?

Я подозреваю, что это audдолжно относиться к серверам ресурсов, а они client_idдолжны относиться к одному из клиентских приложений, распознаваемых сервером аутентификации (например, веб-приложение или приложение iOS).

В моем текущем случае мой сервер ресурсов также является моим клиентом веб-приложения.

Крис Суэйн
источник

Ответы:

134

Как оказалось, мои подозрения оправдались. Заявление аудитории audв JWT предназначено для ссылки на серверы ресурсов, которые должны принимать токен.

Как это сообщение просто ставит его:

Аудитория токена - это предполагаемый получатель токена.

Значение аудитории - это строка - обычно это базовый адрес ресурса, к которому осуществляется доступ, например https://contoso.com.

client_idВ OAuth относится к клиентскому приложению , которое будет запрашивающего ресурсы с сервера ресурсов.

Клиентское приложение (например, ваше приложение iOS) запросит JWT с вашего сервера аутентификации. При этом, она проходит это client_idи client_secretвместе с любыми учетными данными , которые могут потребоваться. Сервер авторизации проверяет клиента с помощью client_idи client_secretи возвращает JWT.

JWT будет содержать audутверждение, определяющее, для каких серверов ресурсов JWT действителен. Если audсодержит www.myfunwebapp.com, но клиентское приложение пытается использовать JWT www.supersecretwebapp.com, доступ будет запрещен, потому что сервер ресурсов увидит, что JWT не предназначен для него.

Крис Суэйн
источник
6
Кажется, что aud тоже может быть client_id. см. tools.ietf.org/id/draft-hunt-oauth-v2-user-a4c-01.txt aud REQUIRED for session_token. Contains the client_id of the client receiving the assertion.
themihai
1
Сервер ресурсов не знает, куда клиенты отправляют JWT. Как сервер ресурсов будет отклонять такой трафик из вашего iOS-приложения на какой-то другой URL? Я не думаю, что ты прав.
Джон Корснес,
Я бы сказал: «Если« aud »содержит« www.webapp.com », но клиентское приложение пытается использовать JWT на« secret.webapp.com »»
катамфетамин
2
RFC говорит, что аудитория (aud) идентифицирует получателей. Получатели получают ваши токены JWT. Если у вас есть веб-приложение, то, вероятно, это может быть contoso.com, но если у вас есть настольное или мобильное приложение (которое выполняет аутентификацию), у аудитории нет URI. Эмитент - это тот, кто генерирует токены JWT, поэтому, скорее всего, это адрес сервера. RFC говорит, что использование этого утверждения НЕОБЯЗАТЕЛЬНО, поэтому используйте его только тогда, когда оно вам нужно.
Конрад
1
На самом деле я не понимаю, в чем будет разница между аудиторией и эмитентом.
Энди
65

Утверждение JWT aud(Аудитория)

Согласно RFC 7519 :

Утверждение «aud» (аудитория) определяет получателей, для которых предназначен JWT. Каждый принципал, предназначенный для обработки JWT, ДОЛЖЕН идентифицировать себя со значением в заявлении аудитории. Если принципал, обрабатывающий заявку, не идентифицирует себя со значением в заявлении "aud", когда это утверждение присутствует, то JWT ДОЛЖЕН быть отклонен. В общем случае значение «aud» представляет собой массив строк с учетом регистра, каждая из которых содержит значение StringOrURI. В особом случае, когда JWT имеет одну аудиторию, значение «aud» МОЖЕТ быть единственной чувствительной к регистру строкой, содержащей значение StringOrURI. Интерпретация ценностей аудитории обычно зависит от конкретного приложения. Использование этого утверждения НЕОБЯЗАТЕЛЬНО.

Утверждение Audience ( aud), как определено в спецификации, является общим и зависит от приложения. Предполагаемое использование - определение предполагаемых получателей токена. То, что имеет в виду получатель, зависит от приложения. Значение аудитории - это либо список строк, либо одна строка, если есть только одно audутверждение. Создатель токена не обеспечивает audправильную проверку, ответственность за определение того, следует ли использовать токен, лежит на получателе.

Каким бы ни было значение, когда получатель проверяет JWT и хочет подтвердить, что токен предназначен для использования в его целях, он ДОЛЖЕН определить, какое значение в audидентифицирует себя, и токен должен проверяться только в том случае, если объявленный идентификатор получателя присутствует в audиске. Не имеет значения, является ли это URL-адресом или какой-либо другой строкой для конкретного приложения. Например, если моя система решает, что идентифицирует себя audс помощью строки: api3.app.comтогда она должна принимать JWT только в том случае, если audутверждение содержит api3.app.comв своем списке значений аудитории.

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

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

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

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

Пример: токены доступа и обновления

Я могу придумать один надуманный (но простой) пример: возможно, мы хотим использовать JWT для доступа и обновления токенов без необходимости реализовывать отдельные ключи и алгоритмы шифрования, а просто хотим гарантировать, что токены доступа не будут проверяться как токены обновления или наоборот. -верс.

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

OAuth ID клиента против JWT audпретензии

Идентификатор клиента OAuth совершенно не связан и не имеет прямого отношения к заявкам JWT aud. С точки зрения OAuth токены являются непрозрачными объектами.

Приложение, которое принимает эти токены, отвечает за анализ и проверку значения этих токенов. Я не вижу особой ценности в указании идентификатора клиента OAuth в audзаявке JWT .

Кекоа
источник
3
Я немного не уверен в том, что "должен идентифицировать себя". RFC7519 полон подобных необъяснимых битов, а также расплывчатых намеков на другие системы аутентификации, которые, вероятно, являются тем местом, где можно найти правильную интерпретацию стандартных полей утверждений. Откровенно говоря, RFC, каким бы полезным он ни был, никогда не должен был выходить из стадии черновика в таком состоянии.
Чак Адамс
1
@ChuckAdams Я отредактировал, чтобы прояснить свои мысли. Я согласен, что RFC очень расплывчатый, особенно в отношении «стандартных утверждений» и того, как и когда их использовать.
Kekoa
2
В настоящее время у нас такое же обсуждение того, как использовать поле aud, и я согласен с тем, что оно предназначено для хранения получателя (того, кто проверяет и принимает токен), а не client_id (того, кто попросил токен действовать на от имени пользователя).
hardysim 05
4

Если вы пришли сюда в поисках OpenID Connect (OIDC): OAuth 2.0! = OIDC

Я понимаю, что это помечено для oauth 2.0, а НЕ OIDC, однако часто наблюдается смешение между двумя стандартами, поскольку оба стандарта могут использовать JWT и audутверждение. И один (OIDC) в основном является расширением другого (OAUTH 2.0). (Я сам наткнулся на этот вопрос, ища OIDC.)

Токены доступа OAuth 2.0 ##

Для токенов доступа OAuth 2.0 существующие ответы довольно хорошо покрывают это. Кроме того, вот один соответствующий раздел из OAuth 2.0 Framework (RFC 6749)

Для общедоступных клиентов, использующих неявные потоки, эта спецификация не предоставляет никакого метода, позволяющего клиенту определить, какому клиенту был выдан токен доступа.
...
Аутентификация владельцев ресурсов для клиентов выходит за рамки данной спецификации. Любая спецификация, которая использует процесс авторизации как форму делегированной клиенту аутентификации конечного пользователя (например, сторонняя служба входа в систему), НЕ ДОЛЖНА использовать неявный поток без дополнительных механизмов безопасности, которые позволили бы клиенту определить, имеет ли доступ токен был выпущен для его использования (например, токен, ограничивающий аудиторию).

Токены идентификатора OIDC ##

У OIDC есть токены ID в дополнение к токенам доступа. Спецификация OIDC явно указывает на использование audутверждения в токенах ID. ( openid-connect-core-1.0 )

ауд
ТРЕБУЕТСЯ. Аудитория, для которой предназначен этот идентификатор. Он ДОЛЖЕН содержать client_id OAuth 2.0 Проверяющей стороны в качестве значения аудитории. Он также МОЖЕТ содержать идентификаторы для других аудиторий. В общем случае значение aud представляет собой массив строк с учетом регистра. В общем частном случае, когда есть одна аудитория, значение aud МОЖЕТ быть одной строкой с учетом регистра.

кроме того, OIDC определяет azpутверждение, которое используется вместе с audкогда audимеет более одного значения.

azp
ДОПОЛНИТЕЛЬНО. Авторизованная сторона - сторона, которой был выдан ID-токен. Если он присутствует, он ДОЛЖЕН содержать идентификатор клиента OAuth 2.0 этой стороны. Это утверждение требуется только в том случае, если идентификатор идентификатора имеет одно значение аудитории и эта аудитория отличается от авторизованной стороны. Он МОЖЕТ быть включен, даже если уполномоченная сторона совпадает с единственной аудиторией. Значение azp - это чувствительная к регистру строка, содержащая значение StringOrURI.

Джозеф А
источник
1
Замечу одну вещь: Oauth2 не требует принудительного использования JWT.
zoran
1

Хотя это и устарело, я думаю, что вопрос актуален даже сегодня

Я подозреваю, что aud должен ссылаться на сервер (ы) ресурсов, а client_id должен ссылаться на одно из клиентских приложений, распознаваемых сервером аутентификации.

Да, слово aud должно относиться к стороне-потребителю токена. А client_id относится к стороне получения токена.

В моем текущем случае мой сервер ресурсов также является моим клиентом веб-приложения.

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

Подумайте о SPA, который потребляет ресурс, защищенный OAuth. В этом сценарии клиентом является SPA. Защищаемый ресурс - это аудитория токена доступа.

Второй сценарий интересен. Существует рабочий проект под названием « Индикаторы ресурсов для OAuth 2.0 », в котором объясняется, где вы можете определить целевую аудиторию в запросе авторизации. Таким образом, полученный токен будет ограничен указанной аудиторией. Кроме того, в Azure OIDC используется аналогичный подход, в котором он разрешает регистрацию ресурса и разрешает запросу аутентификации содержать параметр ресурса для определения целевой аудитории маркера доступа. Такие механизмы позволяют рекламным объявлениям OAuth иметь разделение между клиентом и стороной, потребляющей токены (аудиторией).

Кавинду Додандува
источник