OAuth-приложения

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

Эта функция лицензируется. Если лицензия вашей организации её не включает, обратитесь в CityScreen. Пункт лицензии называется «OAuth-приложения». Без него каждый эндпоинт OAuth на этой странице отвечает 404.

Если адрес вашей организации не является адресом https, два документа обнаружения (см. Эндпоинты) отвечают 503 Service Unavailable, потому что клиенты отправляли бы коды и токены открытым текстом. В этом случае обратитесь в CityScreen.

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

Эндпоинты

Все эндпоинты находятся на адресе вашей организации, например https://deals.example.com. Эндпоинты расположены в корне адреса, и только REST API, который открывают токены, находится под /api.

Адрес Метод Назначение

/oauth/authorize

GET

Запускает поток кода авторизации в браузере сотрудника.

/oauth/token

POST

Выдаёт токены доступа для всех типов авторизации и обновляет их.

/oauth/revoke

POST

Отзывает токен.

/oauth/register

POST

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

/oauth/userinfo

GET, POST

Возвращает claims сотрудника для токена с областью доступа openid, см. Единый вход через OpenID Connect.

/oauth/jwks

GET

Публикует ключи, которыми проверяют ID-токены.

/oauth/end-session

GET, POST

Позволяет приложению запросить выход сотрудника.

/.well-known/openid-configuration и /.well-known/oauth-authorization-server

GET

Описывают сервер и всё перечисленное выше для клиентских библиотек.

Где управляют приложениями

Откройте Сотрудники и затем вкладку OAuth-приложения. Чтобы видеть вкладку, нужно право «OAuth-приложения» Просмотр, см. Роли и права.

В блоке вверху показаны «Издатель (issuer)» и «URL обнаружения» вашей организации с кнопкой Копировать URL обнаружения. В таблице такие столбцы:

Столбец Содержимое

Название

Название и описание приложения и «Зарегистрировал» — сотрудник, который его зарегистрировал.

Идентификатор клиента (client ID)

Идентификатор клиента и «Префикс секрета» — первые символы секрета клиента.

Роли

Роли, с которыми действует приложение с учётными данными клиента.

Последнее использование

Когда приложение в последний раз получило или использовало токен, или «Никогда».

Авторизовавшие сотрудники

Сколько сотрудников разрешили приложение.

Кнопки Создать приложение, Редактировать, Перевыпустить секрет, Удалить и Сменить ключ подписи появляются, когда у вашей роли есть соответствующее право. Сменить ключ подписи описана в разделе Единый вход через OpenID Connect.

Регистрация приложения

  1. Откройте Сотрудники > OAuth-приложения и нажмите Создать приложение.

  2. Заполните форму, описанную ниже.

  3. Нажмите Создать.

  4. Скопируйте секрет клиента из диалога «OAuth-приложение создано», прежде чем нажать Готово.

Для регистрации нужно право «OAuth-приложения» Создание в области организации. Прежде чем регистрировать приложение для того, кто просит, убедитесь, кто просит и в какой системе будет храниться секрет клиента. Приложение с учётными данными клиента действует со своими ролями без какого-либо сотрудника.

Поле Что ввести

Название

Обязательно, до 255 символов.

Описание

До 2000 символов. Укажите, что делает приложение и кто его поддерживает.

Тип авторизации (grant type)

Учётные данные клиента (client credentials) (по умолчанию), Код авторизации или оба. Выбор нельзя изменить после создания.

Выдавать токены обновления

Показывается при выборе Код авторизации и включено по умолчанию; тогда приложение получает токен обновления вместе с токеном доступа.

Публичный клиент (без секрета клиента)

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

Адреса возврата (redirect URI)

Обязательно для типа авторизации «код авторизации». До 10 адресов по 2000 символов каждый, абсолютных, со схемой и без фрагмента (#). Адрес в запросе авторизации должен совпадать с одним из них символ в символ, поэтому косая черта в конце, регистр, порт или запрос делают адрес другим.

Разрешённые области доступа (scopes)

Показывается при выборе Код авторизации; области доступа, которые приложение может запрашивать, см. Области доступа. openid, profile, email и groups отмечены по умолчанию; api отмечает администратор, который хочет, чтобы приложение вызывало REST API. Запрос любой другой области доступа отклоняется.

Адрес уведомления о выходе (back-channel logout URI)

Необязательно для любого типа авторизации; адрес https, который получает сообщение, когда сотрудник выходит, см. Единый вход через OpenID Connect.

Адреса возврата после выхода (post-logout redirect URI)

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

Роли

Показывается при выборе Учётные данные клиента (client credentials); роли, с правами которых действует приложение, см. Учётные данные клиента.

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

Секрет клиента

В диалоге «OAuth-приложение создано» показаны идентификатор клиента, секрет клиента и адрес эндпоинта токенов. Идентификатор клиента никогда не меняется. Секрет клиента начинается с csd_ocs_. Диалог предупреждает: «Скопируйте секрет клиента сейчас. Он показывается один раз и больше показан не будет. Относитесь к нему как к паролю.» Позже в таблице виден только его префикс.

У публичного клиента секрета клиента нет.

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

Для публичного клиента Перевыпустить секрет недоступно.

Учётные данные клиента

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

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

Чтобы получить токен, отправьте POST /oauth/token:

  • Тело — form-urlencoded. Параметры в строке запроса отклоняются.

  • grant_type=client_credentials.

  • Приложение аутентифицируется через HTTP Basic или передаёт client_id и client_secret в теле.

  • scope игнорируется: что токен может делать, определяют роли.

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

Ответ содержит access_token (начинается с csd_oat_), token_type (Bearer) и expires_in в секундах. Этот тип авторизации не выдаёт токен обновления. Когда старый токен истекает, приложение запрашивает новый.

Ошибки — invalid_client (401), unauthorized_client для приложения, у которого нет этого типа авторизации, invalid_request и invalid_target. Когда ответ содержит Retry-After, приложение ждёт указанный период, прежде чем запрашивать снова.

Пример 1: получение токена и вызов API
# 1. Get an access token with the client ID and secret of the application
curl -s https://deals.example.com/oauth/token \
  -u 'app_42:csd_ocs_REPLACE_WITH_THE_CLIENT_SECRET' \
  -d grant_type=client_credentials

Ответ выглядит так, токен сокращён:

{"access_token":"csd_oat_REPLACE","token_type":"Bearer","expires_in":7200}
# 2. Call the REST API with the token; the roles of the application decide what is returned
curl -s https://deals.example.com/api/clients/deals \
  -H 'Authorization: Bearer csd_oat_REPLACE'

Второй вызов возвращает сделки, которые роли приложения разрешают ему читать. Приложение, роли которого ничего не разрешают для сделок, получает 403. 7200 секунд — это срок по умолчанию в 120 минут, см. Срок действия токена.

Код авторизации с PKCE

Поток следует RFC 6749, раздел 4.1 с PKCE (RFC 7636). Сотрудник входит, в том числе с двухэтапной проверкой, если она включена для его учётной записи, и разрешает приложение.

Шаг 1: запрос авторизации

GET /oauth/authorize с такими параметрами:

Параметр Значение

response_type

code.

client_id

Идентификатор клиента приложения.

redirect_uri

Один из зарегистрированных адресов возврата, символ в символ.

scope

Области доступа через пробел, не более 20. Передавайте его явно: зарегистрированное приложение, которое не передаёт ни одной, получает токен без областей доступа.

state

Необязательно, до 2048 символов. Возвращается без изменений.

nonce

Необязательно, до 512 символов. Попадает в ID-токен.

code_challenge и code_challenge_method

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

resource

Необязательно. Адрес ресурса, который обслуживает сервер, например https://deals.example.com/api. Любое другое значение отклоняется с invalid_target. Тогда токены предназначены для этого ресурса, а последующий запрос на них должен указывать тот же ресурс или никакого.

prompt

Необязательно: none, login, consent или select_account, см. Страница согласия.

Ошибка, найденная до проверки клиента и его адреса возврата, показывается на странице CityScreen Deals и никогда не отправляется приложению. Любая другая ошибка возвращает браузер на адрес возврата с error, state и iss.

Шаг 2: браузер возвращается с кодом

После того как сотрудник разрешил приложение, браузер возвращается на адрес возврата с code, state и iss — адресом издателя. Код начинается с csd_oac_, живёт 5 минут и работает один раз. Повторное предъявление использованного кода отзывает токены, выданные по нему.

Шаг 3: обмен кода

POST /oauth/token, form-urlencoded, с параметрами:

  • grant_type=authorization_code;

  • code;

  • redirect_uri — тот же адрес, что и в запросе авторизации;

  • code_verifier, если в запросе авторизации был вызов;

  • конфиденциальный клиент аутентифицируется через HTTP Basic или передаёт client_id и client_secret в теле, а публичный клиент передаёт только client_id.

Ответ содержит access_token, token_type, expires_in и scope. Он также содержит refresh_token (начинается с csd_ort_), если у приложения включено Выдавать токены обновления, и id_token, если среди областей доступа есть openid. Неверный, использованный, просроченный или выданный другому клиенту код, неверный верификатор и неверный адрес возврата дают один и тот же invalid_grant (400). Конфиденциальный клиент с неверным секретом получает вместо этого invalid_client (401). Когда ответ содержит Retry-After, приложение ждёт указанный период, прежде чем пробовать снова.

Шаг 4: обновление

POST /oauth/token с grant_type=refresh_token и refresh_token, с аутентификацией как на шаге 3. scope в запросе игнорируется: новые токены сохраняют области доступа, которые разрешил сотрудник.

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

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

Пример 2: публичный клиент с PKCE
# 1. The application creates a verifier and its S256 challenge
verifier=$(openssl rand -base64 48 | tr '+/' '-_' | tr -d '=\n')
challenge=$(printf '%s' "$verifier" | openssl dgst -sha256 -binary | openssl base64 -A | tr '+/' '-_' | tr -d '=')

# 2. It opens this address in the employee's browser (line breaks added for reading)
#    https://deals.example.com/oauth/authorize
#      ?response_type=code
#      &client_id=app_43
#      &redirect_uri=https%3A%2F%2Ftools.example.com%2Fcallback
#      &scope=api
#      &state=af0ifjsldkj
#      &code_challenge=<the value of $challenge>
#      &code_challenge_method=S256

# 3. The browser comes back to
#    https://tools.example.com/callback?code=csd_oac_REPLACE&state=af0ifjsldkj&iss=https%3A%2F%2Fdeals.example.com

# 4. The application exchanges the code; a public client sends no secret
curl -s https://deals.example.com/oauth/token \
  -d grant_type=authorization_code \
  -d code='csd_oac_REPLACE' \
  --data-urlencode redirect_uri='https://tools.example.com/callback' \
  -d code_verifier="$verifier" \
  -d client_id=app_43

Ответ выглядит так, токены сокращены:

{"access_token":"csd_oat_REPLACE","token_type":"Bearer","expires_in":7200,"scope":"api","refresh_token":"csd_ort_REPLACE"}
# 5. Call the REST API with the employee's access rights
curl -s https://deals.example.com/api/clients/deals \
  -H 'Authorization: Bearer csd_oat_REPLACE'

# 6. When the access token expires, refresh it
curl -s https://deals.example.com/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token='csd_ort_REPLACE' \
  -d client_id=app_43

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

Области доступа

Область доступа Что она разрешает

openid

Делает запрос запросом OpenID Connect. Ответ содержит ID-токен, а токен открывает эндпоинт UserInfo.

profile

Добавляет name, preferred_username и locale в ID-токен и в UserInfo.

email

Добавляет email.

groups

Добавляет groups и group_names, см. Единый вход через OpenID Connect.

api

Позволяет токену вызывать REST API с правами доступа сотрудника.

Токен, выданный сотруднику без области доступа api, открывает только UserInfo. REST API отвечает на него кодом 403, вызовом Bearer error="insufficient_scope", scope="api" и сообщением «The OAuth access token was issued without the api scope, which the CSD API requires. Authorize the application again and allow it to act in CSD.» Токен может делать только то, что при каждом вызове разрешают собственные права сотрудника, а его области доступа ограничивают его дальше.

Токены учётных данных клиента областей доступа не принимают. Запрос любой другой области доступа, в том числе offline_access, отклоняется.

Сотрудник входит и один раз нажимает Разрешить. С областью доступа api приложение затем вызывает REST API с собственными правами доступа этого сотрудника, такими, какие они в момент каждого вызова. Сотрудник видит все разрешённые им приложения в разделе Аккаунт > Авторизации и отзывает разрешение там кнопкой Отозвать.

Форма входа называется «Войдите в {{instance}}, чтобы продолжить в {{application}}», в неё подставляются названия вашей организации и приложения. Она выполняет те же шаги, что и вход через веб, см. Вход и выход. Страница согласия называется «{{application}} запрашивает доступ» и перечисляет, что приложение сможет делать и какие сведения о сотруднике оно получит. На ней есть кнопки Разрешить и Запретить. Запретить отправляет приложению access_denied. У приложения, которое зарегистрировалось само, есть значок «Не проверено» и предупреждение.

Страница пропускается для приложения, которое сотрудник уже разрешил с теми же областями доступа. Параметр prompt это меняет:

prompt Действие

consent

Страница показывается снова.

login или select_account

Сотрудник снова входит на странице.

none

Страница не показывается. Приложение получает код, если сотрудник вошёл и разрешал его раньше, а иначе — login_required или consent_required.

Отзыв в Аккаунт > Авторизации сразу останавливает токены доступа и обновления приложения. Приложение может спросить сотрудника снова. Приложение с адресом уведомления о выходе получает уведомление, см. Единый вход через OpenID Connect.

Приложения, которые регистрируются сами

Некоторые приложения администратор не может зарегистрировать заранее. Они регистрируются через POST /oauth/register, запрос JSON по RFC 7591, и не нуждаются в учётных данных.

Член Правило

redirect_uris

Обязательно, от 1 до 10 адресов без фрагмента и данных пользователя, не более 2000 символов каждый. Каждый — адрес https, адрес http на хосте loopback (127.0.0.1, [::1] или localhost) с портом или адрес с приватной схемой в форме обратного домена, например com.example.app:/callback.

grant_types

Необязательно; принимаются только authorization_code и refresh_token, и регистрируются оба.

response_types

Необязательно; принимается только значение code.

client_name, software_id, software_version

Необязательно, до 255 символов.

client_uri, logo_uri

Необязательно, абсолютные адреса http или https.

Члены выхода

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

Ответ — 201 с client_id вида dcr_<22 characters> и token_endpoint_auth_method, равным none. Секрета клиента нет, поэтому клиент публичный и использует PKCE. Без scope в запросе авторизации клиент получает api. Ошибки — invalid_redirect_uri, invalid_client_metadata и 429 Too Many Requests.

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

Администраторы видят эти записи в таблице и могут их удалять. Их настройки изменить нельзя: «Это приложение зарегистрировалось само, поэтому его настройки нельзя изменить здесь. Его можно удалить.» Когда сотрудник отзывает такое приложение в Авторизации, вместе с ним удаляется запись, для чего нужно право Удаление в области «свои».

Отзыв токенов

POST /oauth/revoke с параметром формы token отзывает токен доступа или токен обновления. Отзыв токена обновления отзывает и всё его семейство: выданные по нему токены доступа и заменившие его токены обновления.

client_id, если передан, должен быть клиентом, которому выдан токен, иначе ничего не отзывается. Ответ — пустой 200 для любого токена, в том числе неизвестного или уже отозванного, поэтому по ответу не видно, какой это токен. Запрос без token получает 400 invalid_request.

Другие способы прекратить действие токенов:

  • сотрудник отзывает авторизацию в Аккаунт > Авторизации;

  • администратор удаляет приложение;

  • сотрудника деактивируют, что удаляет все выданные ему токены OAuth.

Срок действия токена

Администратор задаёт «Срок действия токена доступа для OAuth-приложений (минут)» в Настройки > Общие. Значение — от 5 до 1440 минут, по умолчанию 120. Изменение применяется к токенам, выданным после сохранения. ID-токен живёт столько же, сколько токен доступа, с которым он выдан.

Права

Право Для чего

«OAuth-приложения» Просмотр, Создание, Редактирование и Удаление в области организации

Администраторы, которые регистрируют приложения и управляют ими.

«OAuth-приложения» Создание и Удаление в области «свои»

Сотрудники, которые подключают приложения, регистрирующиеся сами.

«Смена ключа подписи»

Администраторы, которые меняют ключ подписи.

Роли редактируются в разделе Роли и права.