Сервис Фреш поддерживает подключение сторонних приложений с возможностью работы от имени пользователя сервиса через эти сторонние приложения.

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

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

Подключение существующих пользователей

Общая схема аутентификации пользователя при авторизации стороннего приложения

Методы провайдера аутентификации

Метод auth – авторизация приложения после аутентификации пользователя

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

Является частью  Authorization Code Flow –  https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps

Параметры метода:

ПараметрТипОписаниеПример
client_idСтрокаИдентификатор приложения1c.cloud
redirect_uriСтрокаАдрес, на который будет переадресован пользователь после прохождения авторизации.
Должен совпадать с redirect_uri, указанным на этапе добавления стороннего приложения.
https://1c.cloud/callback
response_typeСтрокаТип ответа, который необходимо получить. Поддерживается – code.code
stateСтрокаЛюбое значение, которое провайдер вернет на redirect_uri, например UUID запроса.786a9b4a-9b4c-4aa5-b626-3df5b0a1b44f


Пример вызова:

GET https://{{server}}/a/openid/e1cib/oid2op/auth?client_id=1c.cloud&redirect_uri=https%3A%2F%2F1c.cloud%2Fcallback&response_type=code&state=786a9b4a-9b4c-4aa5-b626-3df5b0a1b44f

Открывается окно аутентификации пользователя.

После аутентификации пользователя, пользователь перенаправляется в окно предоставления доступа приложению:

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

При подтверждении, пользователь будет перенаправлен в redirect_uri стороннего приложения.

Далее стороннее приложение с полученным значением code может авторизоваться и запросить токен доступа методом /token

Метод token – получение токена доступа (access_token) и токена обновления доступа (refresh_token)

Для метода token поддерживаются следующие варианты предоставления (grant_type):

  • authorization_code – для обмена кода доступа на токен при первичной регистрации и подключения уже существующих пользователей после их аутентификации
  • refresh_token – для обновления токенов аутентификации в процессе работы пользователей с общем ЛК.

Для получения access_token приложение выполнит POST-запрос, передав следующие параметры:

ПараметрТипОписание
client_idСтрокаИдентификатор приложения
client_secretСтрокаЗащищенный ключ приложения
grant_typeСтрокаТип запрашиваемого ресурса. Значение равно authorization_code или refresh_token.
codeСтрокаОбязательно при grant_type=authorization_code. Код, полученный после прохождения авторизации
redirect_uriСтрокаОбязательно при grant_type=authorization_code. Адрес, на который был переадресован пользователь после прохождения авторизации. Должен совпадать с redirect_uri, указанным на этапе подключения приложения.
refresh_tokenСтрокаОбязательно при grant_type=refresh_token. Токен обновления доступа.

В результате выполнения запроса приложение получит JSON c токенами.

Пример запроса x-www-form-urlencoded  Развернуть
# @name tokenByCode
POST https://{{server}}/a/openid/e1cib/oid2op/token
Content-Type: application/x-www-form-urlencoded

&client_id=1c.cloud
&client_secret=secret-123Qwer
&grant_type=authorization_code
&code={{authorizationCode.response.body.code}}
&redirect_uri={{authorizationCode.response.body.redirect_uri[0]}}

или

Пример запроса application/json  Развернуть
# @name tokenByCode
POST https://{{server}}/a/openid/e1cib/oid2op/token
Content-Type: application/json

{
  "client_id": "1c.cloud",
  "client_secret": "secret-123Qwer",
  "grant_type": "authorization_code",
  "code": "{{authorizationCode.response.body.code}}",
  "redirect_uri": "{{authorizationCode.response.body.redirect_uri[0]}}",
}
Пример ответа  Развернуть
HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
Cache-Control: no-cache, no-store
Pragma: no-cache
...

{
"token_type": "bearer",
"access_token": "ewoiY...",
"expires_in": 3600,
"refresh_token": "ewoiY...",
"refresh_expires_in": 604800
}

Вариант запроса токена доступа по токену обновления:

Пример запроса  Развернуть
# @name tokenByRefresh
POST https://{{server}}/a/openid/e1cib/oid2op/token
Content-Type: application/x-www-form-urlencoded

&client_id=1c.cloud
&client_secret=secret-123Qwer
&grant_type=refresh_token
&refresh_token={{tokenByCode.response.body.refresh_token}}

Подключение новых пользователей при регистрации в сервисе

Подключение стороннего приложения доступно:

  • Для зарегистрированных пользователей после их аутентификации и авторизации в сервисе Фреш.
  • Непосредственно при регистрации новых пользователей в сервисе Фреш.

Вызов программной регистрации с подключением стороннего приложения

Для подключения стороннего приложения сразу при регистрации новых пользователей в сервисе Фреш нужно использовать следующие методы HTTP-сервиса программной регистрации менеджера сервиса:

Схема регистрации, аутентификации пользователя и авторизации приложения для работы через токен:


Пример получения токенов доступа и их использования при обращении к ExtAPI

Пример для тестирования на VS-Code с плагином Rest Client по порядку вызова методов с вариантами

Примеры вызовов методов по порядку  Развернуть
### Пример получения токенов доступа и их использования при обращении к ExtAPI

# Имя тестового сервера
@server=1cfresh.com

# Логин и пароль пользователя регистрации обслуживающей организации
@promouser=support-reg:123Qwer

# Идентификатор стороннего приложения
@client_id=1c.cloud

# Секрет стороннего приложения
@client_secret=secret-123Qwer

# Адрес перенаправления в стороннее приложение
@redirect_uri=https://1c.cloud/callback

# Логин / почта регистрируемого пользователя
@username=client@yopmail.ru

# Наименование (полное имя) регистрируемого пользователя
@name = client

### Проверка регистрации пользователя в сервисе Фреш
# @name checkUser
POST https://{{server}}/a/adm/hs/promo_reg/check_user
Authorization: Basic {{promouser}}
Content-Type: application/json
  
{
  "email": "{{username}}",
}

### Регистрация нового пользователя или абонента у существующего
# @name signUp
POST https://{{server}}/a/adm/hs/promo_reg/sign_up
Authorization: Basic {{promouser}}
Content-Type: application/json
  
{
  "name": "{{name}}", 
  "email": "{{username}}",
  "phone": "8-800-000-00-00",
  "fast_completion": true,
  "send_notification": true, 
}

### Получение информации о созданном приложении, абоненте и подписке (не обязательно)
# @name getAppURL
POST https://{{server}}/a/adm/hs/promo_reg/get_app_url
Authorization: Basic {{promouser}}
Content-Type: application/json
  
{
  "login": "{{username}}",
  "send_notification": false,
}

### Отправка письма верификации для существующих пользователей (не первичная регистрация)
# @name sendVerification
POST https://{{server}}/a/adm/hs/promo_reg/send_verification
Authorization: Basic {{promouser}}
Content-Type: application/json
  
{
  "email": "{{username}}", 
  "client_id": "{{client_id}}",
  "client_secret": "{{client_secret}}",
  "redirect_uri": "{{redirect_uri}}",
  "state": "786a9b4a-9b4c-4aa5-b626-3df5b0a1b44f"
}

### Получение кода авторизации для новых пользователей (первичная регистрация)
# @name authorizationCode
POST https://{{server}}/a/adm/hs/promo_reg/authorization_code
Authorization: Basic {{promouser}}
Content-Type: application/json
  
{
  "login": "{{username}}", 
  "client_id": "{{client_id}}",
  "client_secret": "{{client_secret}}"
}

### Получение токена доступа пользователя по коду авторизации
### пример с application/x-www-form-urlencoded
# @name tokenByCode
POST https://{{server}}/a/openid/e1cib/oid2op/token
Content-Type: application/x-www-form-urlencoded

&client_id={{client_id}}
&client_secret={{client_secret}}
&grant_type=authorization_code
&code={{authorizationCode.response.body.code}}
&redirect_uri={{authorizationCode.response.body.redirect_uri[0]}}

### пример с application/json
# @name tokenByCode
POST https://{{server}}/a/openid/e1cib/oid2op/token
Content-Type: application/json

{
  "client_id": "{{client_id}}",
  "client_secret": "{{client_secret}}",
  "grant_type": "authorization_code",
  "code": "{{authorizationCode.response.body.code}}",
  "redirect_uri": "{{authorizationCode.response.body.redirect_uri[0]}}",
}

### Получение токена доступа пользователя по токену обновления
# @name tokenByRefresh
POST https://{{server}}/a/openid/e1cib/oid2op/token
Content-Type: application/x-www-form-urlencoded

&client_id={{client_id}}
&client_secret={{client_secret}}—
&grant_type=refresh_token
&refresh_token={{tokenByCode.response.body.refresh_token}}

### Получение списка абонентов пользователя с помощью токена доступа (понадобится для запроса списка подписок)
# @name accountList
GET https://{{server}}/a/adm/hs/ext_api/execute/usr/account/list
Authorization: Bearer {{tokenByRefresh.response.body.access_token}}

### Получение информации о пользователе с помощью токена доступа
# @name userInfo
GET https://{{server}}/a/adm/hs/ext_api/execute/usr/user/info
Authorization: Bearer {{tokenByRefresh.response.body.access_token}}

### Получение действующих подписок пользователя с помощью токена доступа
# @name subscriptionList
POST https://{{server}}/a/adm/hs/ext_api/execute/usr/subscription/list
Authorization: Bearer {{tokenByRefresh.response.body.access_token}}

{
  "auth": {
    "account": {{accountList.response.body.account[0].id}}
  }
}

Вход в приложения сервиса и менеджер сервиса по токену доступа

Схема SSO-входа пользователя через стороннее приложение

Выполнение SSO-входа пользователя через стороннее приложение

После получения токена доступа для SSO-входа в приложение сервиса или менеджер сервиса браузер пользователя должен выполнить POST-запрос к корневому методу провайдера аутентификации, указав параметры:

  • cmd - команда провайдеру аутентификации, может принимать значения:
    • sso – будет возвращен редирект с установкой одноразовой куки
    • token – будет возвращен редирект со входом через одноразовый токен доступа. Этот вариант может использоваться, если установка cookie недоступна, например при работе через iframe.

  • access_token – токен доступа
  • redirect_uri –  URLприложения сервиса или менеджера сервиса, куда нужно выполнить вход

Настройки для использования команды cmd=token

Для успешного входа в приложения при использовании команды cmd=token в vrd-файле публикации приложения нужно указать настройку входа с помощью токена доступа в клиент приложения:

<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
...
    <accessTokenAuthentication> 
        <issuers>
            <issuer name="ServiceUserID"
                    authenticationClaimName="login"
                    authenticationUserPropertyName="name"
                    keyInformation="-----BEGIN PUBLIC KEY-----
                    Использовать ключ из внешней публикации главного узла для hs-сервиса ext_api
                    -----END PUBLIC KEY-----"
        </issuers>
        <accessTokenRecepientName>ApplicationClient</accessTokenRecepientName>
    </accessTokenAuthentication>
</point>


В redirect_uri поддерживаются якоря, например: 

https://1cfresh.example/a/smtl/12345#e1cib/command/Обработка.ИнтерфейсСервиса.Команда.МоиПриложения

Параметр cmd можно указать в строке вызова, а параметры access_token и redirect_uri – в теле запроса в формате urlencoded.

В запросе нужно указать HTTP-заголовок Content-Type: application/x-www-form-urlencoded

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

Пример HTML-страницы для перенаправления пользователя в приложение

В приведенном коде страницы:

  • {{server}} это доменное имя сервера провайдера аутентификации;
  • {{access_token}} это значение параметра access_token (токен доступа);
  • {{redirect_uri}} это значение параметра redirect_uri (URL приложения).
HTML-страница для перенаправления пользователя в приложение
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
        <meta http-equiv='pragma' content='no-cache'/>
        <meta http-equiv='cache-control' content='no-cache'/>
        <meta http-equiv='expires' content='-1'/>
    </head>
    <body onload='document.forms.form.submit()'>
        <form name='form' action='https://{{server}}/a/openid/e1cib/oid2op?cmd=sso' method='post'>
            <input type='hidden' name='access_token' value='{{access_token}}'/> <!-- В параметре value указывается токен доступа -->
            <input type='hidden' name='redirect_uri' value='{{redirect_uri}}'/> <!-- В параметре value указывается URL приложения или менеджера сервиса -->
        </form>
    </body>
</html>

Результат SSO-входа пользователя через стороннее приложение с помощью токена доступа

При использовании команды cmd=sso

Если адрес перенаправления, указанный в параметре redirect_uri, доступен, и токен доступа действителен, то:

  1. Будет установлена одноразовая кука sso_oid2op_auth.
  2. Будет выполнено перенаправление в приложение, указанное в параметре redirect_uri.

Если адрес перенаправления, указанный в параметре redirect_uri, доступен, а токен доступа недействителен, то:

  1. Кука sso_oid2op_auth не будет установлена.
  2. Будет выполнено перенаправление в приложение, указанное в параметре redirect_uri. При этом пользователю будет показано окно аутентификации.

Если адрес перенаправления, указанный в параметре redirect_uri, недоступен, у пользователя откроется страница недоступности.

При использовании команды cmd=token

Если адрес перенаправления, указанный в параметре redirect_uri, доступен, и токен доступа действителен, то будет выполнено перенаправление в приложение, указанное в параметре redirect_uri с одноразовым токеном входа в приложение.

Если адрес перенаправления, указанный в параметре redirect_uri, доступен, а токен доступа недействителен, то будет выполнено перенаправление в приложение, указанное в параметре redirect_uri. При этом пользователю будет показано окно аутентификации.

Если адрес перенаправления, указанный в параметре redirect_uri, недоступен, у пользователя откроется страница недоступности.