В основе работы API Диадока лежит контекст пользователя, поэтому перед началом работы нужно аутентифицироваться.
Аутентификация в Диадоке происходит по протоколу OpenID Connect с помощью сервиса OpenID Провайдера — сервера, который выдает токен доступа к продукту.
Токен доступа (access_token) — уникальный код, который позволяет идентифицировать пользователя и выполнять действия от его имени в API Диадока. Его нужно передавать в методы API в HTTP-заголовке Authorization.
Чтобы реализовать аутентификацию в интеграционном решении, выполните шаги:
Оставьте заявку на странице интеграции. После этого с вами свяжется менеджер, предоставит доступ в Кабинет интегратора и выдаст идентификатор вашего приложения client_id.
Выпустите в Кабинете интегратора ключ приложения client_secret. Для этого:
Сохраните полученный ключ в надежное место: он понадобится для следующих действий. Это секретный ключ, не передавайте его третьим лицам.
Выберите подходящий для вашего приложения алгоритм аутентификации и получите с его помощью токен доступа access_token.
Refresh Token Flow — подходит для роботизированных приложений, не позволяющих взаимодействовать с пользователем для авторизации. Самый простой алгоритм для автоматического обновления токена, подходит для большинства решений.
Authorization Code Flow — подходит для бэкенд-приложений, которые могут отображать страницу авторизации.
Device Authorization Flow — подходит для приложений с ограничениями на ввод данных для аутентификации, например, для desktop-приложений или 1С.
Выбранный способ аутентификации можно изменить в Кабинете интегратора, но изменения применятся не сразу — потребуется около 5 минут.
Используйте полученный токен доступа access_token в заголовке Authorization при вызовах методов API Диадока:
Обратите внимание, что время жизни токена ограничено: токен нужно обновить, пока он еще активен.
Схема Client Credentials Flow для Диадока не подходит: для выпуска токенов нужен первичный пользовательский контекст и подтверждение прав доступа.
Обратите внимание, что запросы авторизации уходят не в Диадок, а на identity.kontur.ru. Поэтому адрес API Диадока для вызова /connect/authorize и /connect/token не подходит.
При авторизации в качестве client_secret нужно передать ключ API со страницы приложения в Кабинете интегратора.
Чтобы приложение работало без участия оператора, обновляйте токен доступа access_token с помощью refresh_token. Срок жизни access_token ограничен, схема обновления описана в разделе Обновление токена.
Токен отражает права того сотрудника, который подтвердил доступ. Поэтому для интеграции лучше использовать сервисную учетную запись с нужными правами, а не личную запись сотрудника. В этом случае схема интеграции не сломается, если сотрудник уйдет из компании или сменит должность. Сохраняйте доступ к сервисной учетной записи и привязанному к ней адресу электронной почты.
В зависимости от реализуемого сценария у учетной записи должны быть определенные права:
отправка документов — право на создание и редактирование документов;
подписание — право подписывать документы;
вызов административных методов (например, CreateEmployee) — права администратора.
Алгоритм подходит для роботизированных приложений, которые не могут взаимодействовать с пользователем для авторизации.
Этот способ получения токена подразумевает, что refresh_token выпускается один раз в Кабинете интегратора, а затем приложение получает access_token без участия оператора — по client_id, client_secret и refresh_token.
Чтобы реализовать эту схему, нужно настроить Кабинет интегратора:
В разделе «Способ получения токенов (clientMode)» выберите значение «AuthorizationCode».
После этого в разделе «Выпуск токенов» выберите необходимые для работы приложения скоупы и нажмите кнопку «Получить refresh-токен».
Если вы впервые выпускаете токен, перед вами появится следующее сообщение.
Нажмите кнопку «Подтвердить» и подождите 2-5 минут, чтобы изменения вступили в силу. После этого снова приступите к выпуску refresh-токена.
В окне выбора учетной записи выберите ту запись, для которой хотите получить токен.
Если вы хотите получить токен для технической учетной записи, а не для текущей, нажмите «Скопировать ссылку». Полученную ссылку откройте в браузере, в котором не проходила авторизация (или в режиме «Инкогнито»), а затем авторизуйтесь под технической учетной записью.
Подтвердите доступы для работы приложения.
Введите API-ключ и нажмите «Получить refresh-токен». Скопируйте полученный refresh-токен и сохраните его для использования в вашем интеграционном решении.
Примечание
После получения refresh-токена вы можете изменить способ получения токенов (clientMode) в вашем приложении на любой другой. Полученный refresh-токен при этом останется активен и будет работать в вашем интеграционном решении без изменений.
С помощью полученного refresh-токена вы можете получить токен доступа access_token по алгоритму обновления. Обновлять refresh-токен не требуется: он будет действителен до тех пор, пока вы не отзовете его в Кабинете интегратора. Срок жизни refresh-токен — 30 дней, счетчик его срока жизни обновляется при каждом использовании refresh-токена для получения токена доступа access_token.
Не забывайте обновлять токен доступа access_token до истечения времени его жизни (обычно составляет 24 часа).
В разделе «Способ получения токенов (clientMode)» выберите значение «AuthorizationCode».
Укажите адрес перенаправления. Если поле адреса пустое, вызов /connect/authorize вернет ошибку. Для тестирования можно указать http://localhost, а для рабочего приложения заведите отдельную страницу под адрес перенаправления.
Примечание
Примеры реализации описанного алгоритма можно посмотреть в проекте веб-приложения.
Вы можете использовать примеры, чтобы не реализовывать взаимодействие с OpenID Провайдером самостоятельно.
Чтобы получить токен доступа, выполните следующие шаги:
Получите временный код подтверждения.
Для этого перенаправьте пользователя из приложения на страницу авторизации с помощью запроса GET/connect/authorize сервиса OpenID Провайдера.
В ответ OpenID Провайдер запросит у пользователя данные для входа и разрешения, а затем перенаправит его на указанный вами адрес и вернет в нем временный код подтверждения.
Подробнее
Параметры запроса GET /connect/authorize
response_type — ответ, который нужно получить от OpenID Провайдера. Укажите значение code.
client_id — идентификатор вашего приложения.
scope — список прав доступа, которые необходимы приложению в текущей сессии. Укажите следующие значения для доступа к данным Диадока:
openid — для взаимодействия с Провайдером по OpenID Connect,
profile — для получения основной информации о пользователе,
email — для получения адреса электронной почты пользователя,
offline_access — для доступа к refresh_token для обновления токена,
Diadoc.PublicAPI.Staging — для работы с тестовой площадкой Диадока,
Diadoc.PublicAPI — для работы с главной площадкой Диадока.
redirect_uri — адрес ресурса интегратора, на который будет перенаправлен пользователь после аутентификации. Передайте в этом параметре адрес своего ресурса, на котором вы сможете принять перенаправление и обработать параметры адреса. OpenID Провайдер получит данные пользователя для входа и разрешения, а затем перенаправит пользователя на указанный адрес, вернув в его параметрах временный код подтверждения. Такой же адрес должен быть указан в списке разрешенных адресов в Кабинете интегратора.
nonce — строка, предназначенная для проверки того, что запрос связан с токеном доступа. Она должна вернуться при получении токена доступа.
Все передаваемые параметры должны быть в формате url_encoded.
В строке BackUrl в качестве разделителя используются значения \u0026. После получения ссылки нужно заменить эти значения на амперсанд (&) и открыть ссылку в браузере. После этого пользователь должен подтвердить доступ кнопкой «Разрешить» под той учетной записью, от имени которой будут отправляться запросы.
После того, как пользователь введет свои данные и выдаст разрешения на странице аутентификации, OpenID Провайдер перенаправит его на адрес, указанный в поле redirect_uri. В нем будет содержаться сгенерированный временный код подтверждения и другие параметры.
Параметры ответа в строке URL:
code — временный код подтверждения, который нужно обменять на токен доступа access_token на следующем этапе авторизации.
state — строка состояния, которую OpenID Провайдер возвращает без изменения.
scope — список прав доступа, которые выдал пользователь вашему приложению.
error — ошибка аутентификации access_denied. Возвращается вместо кода подтверждения, если пользователь или сервер по какой-то причине не выдал разрешение на доступ к данным.
HTTP/1.1 302 Found
Location: https://www.example.com
?error=access_denied
&error_description=
&state=af0ifjsldkj
Обменяйте временный код подтверждения на токен доступа access_token.
Для этого выполните запрос POST/connect/token сервиса OpenID Провайдера.
В ответе метод вернет токен доступа access_token, время его жизни и токен обновления refresh_token, с помощью которого можно обновить токен доступа.
Подробнее
Параметры запроса POST /connect/token:
grant_type — способ запроса токена. Укажите значение authorization_code.
code — временный код подтверждения. Код действителен в течение 5 минут. Если время истекло, необходимо перенаправить пользователя на страницу авторизации.
client_id — идентификатор вашего приложения.
client_secret — ключ вашего приложения.
redirect_uri — адрес, на который получен код подтверждения.
Все передаваемые параметры должны быть в формате url_encoded.
Если запрос был выполнен успешно, OpenID Провайдер вернет в ответе токен доступа access_token и токен для обновления refresh_token.
Если токен выдать не удалось, OpenID Провайдер вернет в ответе ошибку.
Параметры ответа POST /connect/token:
access_token — токен доступа.
token_type — тип токена. Всегда имеет значение Bearer.
refresh_token — токен для обновления токена доступа.
expires_in — время жизни токена доступа access_token в секундах.
Алгоритм подходит для приложений, в которых пользователю сложно вводить данные для аутентификации, например: desktop-приложения, консольные приложения, смарт-устройства, телевизоры. Этот способ получения токена подразумевает, что вместо своих данных пользователь может ввести в браузере некий код, полученный от приложения.
Параметры ответа POST /connect/deviceauthorization:
device_code — временный код подтверждения, который нужно обменять на токен доступа access_token.
user_code — код, который пользователь должен ввести на странице ввода кода в приложении.
verification_uri — URI страницы, на которую нужно перенаправить пользователя для ввода кода, если приложение не умеет открывать пользовательский браузер.
verification_uri_complete — URI страницы, на которую нужно перенаправить пользователя в браузере.
interval — периодичность попыток обмена device_code на access_token в секундах.
expires_in — время жизни временного кода подтверждения device_code в секундах.
Перенаправьте пользователя на страницу авторизации, где он должен ввести свои данные и выдать доступ вашему приложению.
Подробнее
Это можно сделать следующими способами:
Открыть в браузере ссылку, полученную в verification_uri_complete.
Отрисовать пользователю QR-код со ссылкой, полученной в verification_uri_complete. Отсканировав этот код, пользователь перейдет на страницу авторизации.
После этого пользователь должен перейти по предложенной ссылке на своем персональном устройстве, авторизоваться и разрешить вашему приложению получить доступ к данным.
Обратите внимание, что ссылка действительна в течение ограниченного срока — этот срок возвращается в поле expires_in и обычно составляет 300 секунд. Если пользователь за это время не успеет использовать ссылку из verification_uri_complete, то нужно будет повторить первый этап и получить новую ссылку.
Обменяйте временный код подтверждения на токен доступа access_token.
В то время, как пользователь авторизуется, приложение должно периодически выполнять запрос POST/connect/token к сервису OpenID Провайдера до тех пор, пока не получит токен доступа или ошибку.
Подробнее
В ответ на запрос POST/connect/token OpenID Провайдер может вернуть:
ошибку authorization_pending — пользователь не завершил авторизацию.
ошибку access_denied — на странице авторизации пользователь отказался выдать требуемый доступ.
ошибку expired_token — срок действия временного кода подтверждения истек.
токен доступа access_token — пользователь авторизовался и выдал требуемый доступ.
Приложение должно повторять запрос все время, пока OpenID Провайдер возвращает в ответ authorization_pending.
Параметры запроса POST /connect/token:
grant_type — способ запроса токена. Укажите значение urn:ietf:params:oauth:grant-type:device_code.
client_id — идентификатор вашего приложения.
client_secret — ключ вашего приложения.
scope — список прав доступа, которые необходимы приложению в текущей сессии.
device_code — временный код подтверждения.
Все передаваемые параметры должны быть в формате url_encoded.
Если запрос был выполнен успешно, OpenID Провайдер вернет в ответе токен доступа access_token и токен для обновления refresh_token.
Если токен выдать не удалось, OpenID Провайдер вернет в ответе ошибку.
Параметры ответа POST /connect/token:
access_token — токен доступа.
id_token — токен авторизации.
refresh_token — токен для обновления токена доступа.
token_type — тип токена. Всегда имеет значение Bearer.
expires_in — время жизни токена доступа access_token в секундах.
scope — список прав доступа, которые выдал пользователь вашему приложению.
Время жизни токена доступа access_token ограничено. Это значит, что по его истечении пользователю нужно будет заново проходить авторизацию, иначе методы API будут возвращать ошибки. Чтобы не повторять операцию авторизации, достаточно один раз получить от пользователя разрешения и подтверждения, получить access_token, а после — только обновлять полученный токен. Так работает «авторизация без участия пользователя».
Обратите внимание, что обновление токена нужно реализовать на стороне приложения самостоятельно: готовой настройки для этого нет.
Токен access_token нужно обновить до истечения времени его жизни. Определить время жизни можно с помощью поля expires_in, которое возвращается вместе с токеном доступа.
Чтобы обновить токен доступа, используйте один из следующих способов:
повторно отправьте пользователя на страницу авторизации OpenID Провайдера:
Сохраните из ответа access_token и refresh_token. В поле expires_in вернется срок жизни access_token в секундах (обычно 86400 секунд).
Обменяйте refresh_token на новую пару токенов до конца периода expires_in. Рекомендуем менять токены заранее — например, раз в 12 часов.
Замените сохраненный refresh_token значением из ответа. При каждом обмене приходит новый токен, старый больше не понадобится.
Повторяйте обмен не реже раза в 30 дней — столько действителен refresh_token.
выполните запрос POST/connect/token сервиса OpenID Провайдера с refresh_token, полученным вместе с access_token.
Примечание
Обратите внимание, что refresh_token вернется в ответе POST/connect/token только если при запросе GET/connect/authorize или POST/connect/deviceauthorization в параметре scope указан offline_access.
Подробнее
Параметры запроса POST /connect/token:
grant_type — способ запроса токена. Укажите значение refresh_token.
client_id — идентификатор вашего приложения.
client_secret — ключ вашего приложения.
refresh_token — токен для обновления токена доступа.
Все передаваемые параметры должны быть в формате url_encoded.
Обновление токенов без участия пользователя прекращается в следующих случаях:
в scope не указан offline_access: в этом случае refresh_token не вернется;
сохраненное в приложении значение refresh_token не заменено на новое из ответа: в этом случае при следующем обновлении будет использован старый токен, время жизни которого истекло;
токен не обновлялся больше срока своей жизни (обычно 30 дней): в этом случае его действие истекает и пользователю придется выдавать разрешение заново;
у пользователя, который выдал разрешение, больше нет прав на выдачу: в этом случае сервис вернет ошибку 403(Forbidden).
Методы Диадока, которые работают с ящиком, контролируют доступ пользователя к этому ящику по следующему алгоритму:
Диадок извлекает из HTTP-заголовка Authorization значение параметра access_token и с его помощью определяет идентификатор пользователя. Если какое-то действие не удалось выполнить, метод вернет код ошибки 401(Unauthorized). Это возможно в следующих случаях:
в запросе отсутствует HTTP-заголовок Authorization,
в HTTP-заголовке Authorization не указан access_token,
токен поврежден или просрочен.
По идентификатору пользователя Диадок находит ящики, к которым у пользователя есть доступ.
Диадок извлекает из параметров запроса идентификатор ящика. Если идентификатор ящика не входит в список ящиков, доступных пользователю, метод вернет код ошибки 403(Forbidden).
Используйте ключ той площадки, к которой обращаетесь.
403(Forbidden) при обращении к ящику
Токен и ящик относятся к разным площадкам.
Идентификатор ящика, полученный методом
GetOrganization на главной площадке, не
подойдет для использования на тестовой площадке, и
наоборот.
Для каждой площадки получите и используйте разные
идентификаторы ящиков.
403(Forbidden) с текстом «У вас нет права
подписи в организации». В заголовках ответа —
DocumentService.EmployeeCannotSignDocuments.
У авторизовавшегося пользователя недостаточно прав.
Выдайте пользователю права по инструкции «Настройка прав
сотрудника».
/connect/token не отдает токен по коду из
Authorization Code Flow
Срок жизни кода истек: обычно он живет 5 минут.
Повторите первый этап авторизации.
Invalidauthtoken
Токен содержит лишний префикс или опечатки.
Убедитесь, что токен введен корректно и без опечаток.
Правильный вид заголовка —
Authorization:Bearer<access_token>, без
access_token=.
invalid_client при запросе токена в Postman
Запрос оформлен неверно.
Тело запроса заполнено на вкладке
x-www-form-urlencoded, а не raw или
form-data.
Заголовок Authorization удален из запроса токена.
Ключ client_secret передается в теле запроса, а не
в параметрах.
В качестве ключа client_secret используется ключ
API из приложения в Кабинете интегратора.
Запрос отправляется к методу того алгоритма,
который был выбран в приложении в Кабинете
интегратора. Например, если в приложении выбран
алгоритм Authorization Code Flow, а запрос отправлен
на /connect/deviceauthorization, сервис вернет
ошибку invalid_client.