WebSSO Login API
| Документ предназначен для внутреннего использования |
1. Схема аутентификации
Цветом выделены состояния которые передают управление виджету.
| Из всех визуальных состояний есть переходы "cancel" и "fail", завершающие цепочку. Не представлено на схеме для сокращения. Из-за невозможности редактора создавать блоки на схеме с одним заголовком, состояние social разделено на social1.1, social1.2, social1.3. В действительности все они являются реализацией одного функционала. Архитектура состояния social рассмотрено в 6 пункте. Архитектура состояния login_captcha рассмотрено в 3 пункте. Архитектура состояния login_otp рассмотрено в 4 пункте. Архитектура состояния login_router рассмотрено в 2 пункте. |
6. Схема работы модуля входа через социальные сети
Цветом выделены состояния которые передают управление виджету.
| Из всех визуальных состояний есть переходы "cancel" и "fail", завершающие цепочку. Не представлено на схеме для сокращения. Из-за невозможности редактора создавать блоки на схеме с одним заголовком, состояние login разделено на login2.1, login1.1. В действительности login1.1 представляет собой вход через соцсети, а login2.1 проверяет введенные логин и пароль пользователя. Архитектура состояния login1.1 рассмотрено в 8 пункте. Архитектура состояния otp рассмотрено в 9 пункте. Архитектура состояния login_router рассмотрено во 2 пункте. Архитектура состояния login_captcha рассмотрено в 3 пункте. Архитектура состояния login2.1 рассмотрено в 5 пункте. Архитектура состояния attach рассмотрено в 7 пункте. |
7. Схема работы модуля привязки аккауннта социальной сети
Цветом выделены состояния которые передают управление виджету.
| Из всех визуальных состояний есть переходы "cancel" и "fail", завершающие цепочку. Не представлено на схеме для сокращения. Из-за невозможности редактора создавать блоки на схеме с одним заголовком, состояние otp разделено на otp1.1, otp1.2. В действительности все они являются реализацией одного функционала. Архитектура состояния otp рассмотрено в 10 пункте. |
11. Точка входа
Все цепочки аутентификации должны начинаться с OAuth 2.0 endpoint-а.
Например:
-
OAuth 2.0 http://<sso_host>/sso/oauth2/authorize?response_type=code&realm=/customer&client_id=ocb_lk&redirect_uri=http://<sso_host>/sso/secure/lk.jsp&scope=sso/oauth2/authotionType
12. Блокировки
После com.rooxteam.uidm.captcha.limit (default 2) неверных попыток ввода пароля для одного и того же логина требуется вводить CAPTCHA. После com.rooxteam.uidm.block.limit (default 10) неверных попыток ввода пароля или CAPTCHA для одного и того же логина происходит временная блокировка по логину на com.rooxteam.uidm.block.seconds секунд (default 3600 c = 1 час). com.rooxteam.uidm.block.limit включает в себя com.rooxteam.uidm.captcha.limit, то есть при значениях по умолчанию достаточно 2 неверных вводов пароля и 8 неверных ввода CAPTCHA чтобы заблокироваться. После com.rooxteam.uidm.auth.fail.ip.block.limit (default 240) неверных попыток ввода логина/пароля/CAPTCHA с одного и того же IP-адреса в течение com.rooxteam.uidm.block.ip.count.period.seconds секунд (default 86400 с = 24 часа) происходит блокировка этого адреса на com.rooxteam.uidm.block.ip.seconds секунд (default 86400 с = 24 часа)
13. API для виджета логина.
13.1. Общий механизм взаимодействия
Для аутентификации пользователя по протоколу OAuth будет происходить запрос со стороннего ресурса (например Личный Кабинет) на WebSSO, где взаимодействие WebSSO сервера с виджетом происходит путем встраивания кода виджета (HTML код) в WebSSO страницу через запрос на WRS с передачей параметров встраивания. А так же начальных данных (параметр up_inputData) в виде JSON объекта для отрисовки виджета.
Пример начальных данных:
{
"form": {
"errors": [],
"name": "loginForm",
"fields": {
"username": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 10,
"max": 25
}
},
{
"name": "FilteredSize",
"attributes": {
"skip": "(^[^9]+)|([^0-9])",
"message": "symbols {skip} should be filtered out, and resulting string should have length between {min} and {max}",
"min": 10,
"max": 10
}
}
]
},
"password": {
"constraints": [
{
"name": "Size",
"attributes": {
"min": 4,
"max": 1024
}
},
{
"name": "NotNull"
}
]
}
}
},
"view": {
"logoutReason": "idle_timeout",
"isBlocked": false,
"utm": {}
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "auth_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
| имя | обязательный | описание | ограничения (constraints) |
|---|---|---|---|
serverUrl |
да |
URL для следующего запроса |
валидный абсолютный URL |
execution |
да |
Идентификатор предсессии аутентификации |
|
step |
да |
Код состояния |
всегда auth_form |
view |
да |
Дополнительные данные текущего шага |
|
view.msisdn |
да |
Номер телефона, на который будет отправлен OTP SMS |
11 цифр, первая всегда 7 |
view.otpCodeAvailableAttempts |
да |
Кол-во попыток ввода OTP кода |
2 цифры |
view.nextOtpCodePeriod |
да |
Время в секундах до наступления возможности отправки нового OTP кода |
секунды |
view.isBlocked |
да |
Признак блокировки пользователя |
boolean |
view.blockedFor |
нет |
Время до разблокировки в секундах, не передается если view.isBlocked == false |
long |
view.logoutReason |
нет |
Причина логаута пользователя (см.ниже) |
long |
view.utm |
нет |
Содержит GET-параметры вида "utm_", переданные в исходном запросе. Используется для передачи UTM-контекста в цепочке редиректов |
|
form |
нет |
Если есть параметр form, значит надо будет отрисовать форму с полями (fields) внутри объекта |
|
form.fields |
нет |
Список заполняемых данных пользователем |
|
fields.username |
да |
Номер телефона |
|
fields.password |
да |
Пароль |
|
form.constraints |
нет |
Список ограничений на поле |
|
constraints.name |
нет |
Название ограничения поля формы, обязательно для каждого ограничения |
|
constraints.attributes |
нет |
Атрибуты ограничения формы |
|
constraints.attributes.regexp |
нет |
Регулярное выражение (обязательно для ограничения Pattern) |
|
constraints.attributes.flags |
нет |
Флаги регулярного выражения (обязательно для ограничения Pattern) |
|
constraints.attributes.min |
нет |
Минимальное значение длинны поля (обязательно для ограничения Size) |
|
constraints.attributes.max |
нет |
Максимальное значение длинны поля (обязательно для ограничения Size) |
|
form.errors[].message |
нет |
Сообщение об ошибке валидации |
|
form.errors[].field |
нет |
Поле в котором найдена ошибка |
13.1.1. Logout Reason
В первоначальных данных для виджета может быть указан параметр logoutReason. В этом случае нужно отобразить пользователю сообщение о причине логаута и попадания на виджет логина.
Возможные значения: 1. session_timeout - Истечение времени сессии 2. idle_timeout - Бездействие пользователя в течение определенного времени
13.2. Вход в ЛК
Для аутентификации по OAuth протоколу пользователь будет перенаправлен на страницу входа, где будет отрисован виджет с формой для ввода логина и пароля.
13.3. Форматы запросов и ответов
13.3.1. Формат запроса на смену состояния
POST <sso_host>/sso/auth/websso
Accept: application/json
Content-Type: application/x-www-form-urlencoded
| Параметры обязательные для всех запросов |
execution:<executionId> _eventId:<eventId>
-
<sso_host> - базовый адрес сервера SSO, например sso.rooxteam.com
-
<executionId> - брать из переданного JSON объекта, параметр execution
-
<eventId> - идентификатор действия, определяется отдельно для каждого состояния (для captcha_auth_form нужно передавать next)
-
для запроса новой "капчи" на captcha_auth_form - <eventId> должен быть равен updateCaptcha
-
13.3.2. Состояние auth_form
Состояние используется для отображения формы входа через логин пароль. Форма отображается в двух сценариях:
-
как стартовый экран всего виджета, тогда она используется для входа через логин-пароль
-
как шаг сценария создания привязки с соцсетями, тогда она используется для подтверждения пользователя
Принято решение для этих двух целей использовать одну и ту же форму. Признаком, отличающим сценарии является view-переменная socialNetworkId, которая имеет значение - id соцсети (vkontakte, odnoklassniki) если форма отображается в сценарии создания привязки, и отсутствует (или принимает значение null, что одно и то же), если форма отображается в сценарии входа через логин-пароль.
Входные данные (от сервера к виджету)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
vkontakteAppId |
да |
Идентификатор приложения Вконтакте |
строка |
odnoklassnikiAppId |
да |
Идентификатор приложения в Одноклассниках |
строка |
odnoklassnikiRedirectUri |
да |
Один из зарегистрированных redirect uri для приложения в сети Одноклассники. |
строка |
vkontakteRequestScopesAsArray |
нет |
Скоупы для приложения Вконтакте |
массив строк |
odnoklassnikiRequestScopesAsArray |
нет |
Скоупы для приложения в Одноклассниках |
массив строк |
avatarUrl |
нет |
Адрес фотографии аккаунта соц. сети для привязки |
|
firstName |
нет |
Имя пользователя аккаунта соц. сети для привязки |
|
fullName |
нет |
Полное имя пользователя аккаунта соц. сети для привязки |
|
socialNetworkId |
да |
Идентификатор соц. сети (vkontakte, odnoklassniki) для привязки |
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
avatarUrl |
нет |
Адрес фотографии аккаунта соц. сети для привязки |
|
firstName |
нет |
Имя пользователя аккаунта соц. сети для привязки |
|
fullName |
нет |
Полное имя пользователя аккаунта соц. сети для привязки |
|
socialNetworkId |
да |
Идентификатор соц. сети (vkontakte, odnoklassniki) для привязки |
Пример с ошибкой валидации
{
"form": {
"errors": [
{
"message": "size must be not less than 10",
"field": "username"
}
],
"name": "loginForm",
"fields": {
"username": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 10,
"max": 25
}
},
{
"name": "FilteredSize",
"attributes": {
"skip": "(^[^9]*)|([^\\d])",
"min": 10,
"max": 10
}
}
]
},
"password": {
"constraints": [
{
"name": "Size",
"attributes": {
"min": 4,
"max": 1024
}
},
{
"name": "NotNull"
}
]
}
}
},
"view": {
"isBlocked": false,
"vkontakteAppId": "1000121",
"vkontakteRequestScopesAsArray": [
"1",
"2"
]
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "auth_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
Пример с ошибкой аутентификации
{
"form": {
"errors": [
{
"message": "invalid_credentials"
}
],
"name": "loginForm",
"fields": {
"username": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 10,
"max": 25
}
},
{
"name": "FilteredSize",
"attributes": {
"skip": "(^[^9]*)|([^\\d])",
"min": 10,
"max": 10
}
}
]
},
"password": {
"constraints": [
{
"name": "Size",
"attributes": {
"min": 4,
"max": 1024
}
},
{
"name": "NotNull"
}
]
}
}
},
"view": {
"isBlocked": false
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "auth_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
Пример с заблокированным пользователем
{
"form": {
"errors": [
{
"message": "user_blocked"
}
],
"name": "loginForm",
"fields": {
"username": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 10,
"max": 25
}
},
{
"name": "FilteredSize",
"attributes": {
"skip": "(^[^9]*)|([^\\d])",
"min": 10,
"max": 10
}
}
]
},
"password": {
"constraints": [
{
"name": "Size",
"attributes": {
"min": 4,
"max": 1024
}
},
{
"name": "NotNull"
}
]
}
}
},
"view": {
"blockedFor": 123456,
"isBlocked": true
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "auth_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
Выходные данные (от виджета к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
_eventId |
да |
Следующий сценарий: vkontakte, odnoklassniki - вход через соответствующую соцсеть; next - для входа через логин-пароль; |
|
username |
да для сценария входа через логин-пароль |
Логин пользователя |
набор из символов, минимум 1, максимум 1024 |
password |
да для сценария входа через логин-пароль |
Пароль пользователя |
1-1024 символа |
socialData |
да для сценария входа через соцсети |
Информация от API кнопки входа через соцсети. Описание алгоритма формирования socialData |
|
loginType |
да для сценария входа через соцсети |
Способ входа через соцсеть |
всегда строка "WEBSITE" |
13.3.3. Состояние srp_auth
Состояние проводит аутентификации по протоколу SRP.
Клнфигурация:
И для клиента и для сервера устанавлюваются общие константы:
| Параметр | Описание | Пример |
|---|---|---|
com.rooxteam.widgets.srp.n |
"безопасное простое" = 2*q+1 простое, где q тоже простое число. Число в 10-чной системе. |
11144252…13345603 |
com.rooxteam.widgets.srp.g |
генератор по модулю N => для любого 0 < X < N существует и единственный x такой, что g^x % N = X. |
2 |
com.rooxteam.widgets.srp.h |
односторонняя функция хеширования, достаточно безопасная на текущий момент |
SHA-1 |
com.rooxteam.widgets.srp.salt_bytes |
размер соли в байтах |
16 |
| Параметр | Описание | Пример |
|---|---|---|
com.rooxteam.sso.srp.n |
"безопасное простое" = 2*q+1 простое, где q тоже простое число. Число в 10-чной системе. |
11144252…13345603 |
com.rooxteam.sso.srp.g |
генератор по модулю N => для любого 0 < X < N существует и единственный x такой, что g^x % N = X. |
2 |
com.rooxteam.sso.srp.h |
односторонняя функция хеширования, достаточно безопасная на текущий момент |
SHA-1 |
com.rooxteam.sso.auth_with_challenge |
(boolean) включить аутентификацию через SRP-Challenge |
true |
Сценарий аутентификации:
| Шаг | Клиент | Сервер |
|---|---|---|
1 |
- Получает от пользователя логин login и пароль password - Отправляет серверу login |
- Вытаскивает из базы соль salt и верификатор verifier по логину login - Вычисляет переменную B = step1(login, salt, verifier) - Возвращает клиенту salt и B |
2 |
- Вычисляет и передаёт серверу A и M1 |
- Проверяет, можно ли доверять A и M1 - Успешно завершает аутентификацию - Вычисляет и отправляет клиенту M2 |
3 |
- Проверяет, можно ли доверять М2 |
Шаг 1
Выходные данные (от клиента к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
_eventId |
да |
next |
|
username |
да |
Логин пользователя |
набор из символов, минимум 1, максимум 1024 |
password |
да |
Требуется любое непустое значение |
набор из символов, минимум 1, максимум 1024 |
Входные данные (от сервера к клиенту)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
execution |
да |
Идентификатор предсессии аутентификации |
|
view.salt |
да |
Соль |
Число в 16-чном формате |
view.B |
да |
Переменная B |
Число в 16-чном формате |
Шаг 2
Выходные данные (от клиента к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
_eventId |
да |
next |
|
A |
да |
Переменная A |
Число в 16-чном формате |
M1 |
да |
Переменная M1 |
Число в 16-чном формате |
Входные данные (от сервера к клиенту)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
execution |
да |
Идентификатор предсессии аутентификации |
|
view.M2 |
да |
Переменная M2 |
Число в 16-чном формате |
13.3.4. Состояние captcha_auth_form
Состояние может отрисовываться как в сценарии входа по логину-паролю, так и в сценарии создания привязки с соцсетями.
Входные данные (от сервера к виджету)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
serverUrl |
да |
URL для следующего запроса |
|
execution |
да |
Идентификатор предсессии аутентификации |
|
step |
да |
Код состояния |
всегда captcha_auth_form |
view.recaptchaSiteKey |
да |
Ключ для формирования response для последующей валидации ReCaptcha |
|
form.errors[].message |
нет |
Сообщение об ошибке валидации |
|
form.errors[].field |
нет |
Поле в котором найдена ошибка |
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
avatarUrl |
нет |
Адрес фотографии аккаунта соц. сети для привязки |
|
firstName |
нет |
Имя пользователя аккаунта соц. сети для привязки |
|
fullName |
нет |
Полное имя пользователя аккаунта соц. сети для привязки |
|
socialNetworkId |
да |
Идентификатор соц. сети (vkontakte, odnoklassniki) для привязки |
Пример
{
"form": {
"errors": [
{
"field": "captchaCode",
"message": "invalid_captcha"
}
],
"name": "captchaLoginForm",
"fields": {
"username": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 10,
"max": 25
}
},
{
"name": "FilteredSize",
"attributes": {
"skip": "(^[^9]*)|([^\\d])",
"min": 10,
"max": 10
}
}
]
},
"password": {
"constraints": [
{
"name": "Size",
"attributes": {
"min": 4,
"max": 1024
}
},
{
"name": "NotNull"
}
]
}
}
},
"view": {
"recaptchaSiteKey": "6Lf5CQkUAAAAA3shbFPdp0b7HEWJivKgKFuAcNtR"
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "captcha_auth_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
Выходные данные (от виджета к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
username |
да |
Номер телефона |
набор из символов, минимум 10, максимум 25 |
password |
да |
Пароль |
4-1024 символа |
gRecaptchaResponse |
да |
Response сформированный рекапчей для валидации |
13.3.5. Состояние show_attach_form
Входные данные (от сервера к виджету)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
step |
да |
Код состояния |
всегда attach_form |
avatarUrl |
нет |
Адрес фотографии аккаунта соц. сети для привязки |
|
firstName |
нет |
Имя пользователя аккаунта соц. сети |
|
fullName |
нет |
Полное имя пользователя аккаунта соц. сети |
|
socialNetworkId |
да |
Идентификатор соц. сети (vkontakte, odnoklassniki) |
Выходные данные (от виджета к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
_eventId |
да |
Следующий сценарий |
"next" для продолжения или "cancel" для отмены |
13.3.6. Состояние show_reattach_form
Входные данные (от сервера к виджету)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
step |
да |
Код состояния |
всегда reattach_form |
avatarUrl |
нет |
Адрес фотографии аккаунта соц. сети для привязки |
|
firstName |
нет |
Имя пользователя аккаунта соц. сети |
|
fullName |
нет |
Полное имя пользователя аккаунта соц. сети |
|
oldAvatarUrl |
нет |
Адрес фотографии аккаунта соц. сети для удаления привязки |
|
oldFullName |
нет |
Полное имя пользователя аккаунта соц. сети для удаления привязки |
|
socialNetworkId |
да |
Идентификатор соц. сети (vkontakte, odnoklassniki) |
Выходные данные (от виджета к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
_eventId |
да |
Следующий сценарий |
"next" для продолжения или "cancel" для отмены |
13.3.7. Состояние enter_otp_form
Входные данные (от сервера к виджету)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
serverUrl |
да |
URL для следующего запроса |
|
execution |
да |
Идентификатор предсессии аутентификации |
|
step |
да |
Код состояния |
всегда enter_otp_form |
expireOtpCodeTime |
да |
Время действия одноразового пароля в секундах |
секунды |
otpCodeAvailableAttempts |
да |
Кол-во попыток ввода OTP кода |
|
nextOtpCodePeriod |
да |
Время в секундах до наступления возможности запросить новое sms с OTP кодом |
секунды |
otpCodeNumber |
нет |
Номер отправленного смс сообщения |
|
form.errors[].message |
нет |
Сообщение об ошибке |
Выходные данные (от виджета к серверу)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
otpCode |
да |
Одноразовый пароль |
Цифры от 0 до 9, длиной 4 символа |
_eventId |
да |
Следующий сценарий |
"send" для повторной отправки смс, "cancel" для отмены, "start" для продолжения |
Пример с ошибкой валидации кода
{
"form": {
"errors": [
{
"field": "otpCode",
"message": "invalid_otp"
}
],
"name": "otpForm",
"fields": {
"otpCode": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 4,
"max": 4
}
},
{
"name": "Pattern",
"attributes": {
"regexp": "[0-9]+"
}
}
]
}
}
},
"view": {
"otpCodeAvailableAttempts": 2,
"msisdn": "79876543210",
"nextOtpCodePeriod": 120,
"blockedFor": 0,
"isBlocked": false
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "enter_otp_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
Пример с превышением кол-ва попыток
{
"form": {
"errors": [
{
"field": "otpCode",
"message": "too_many_wrong_code"
}
],
"name": "otpForm",
"fields": {
"otpCode": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 4,
"max": 4
}
},
{
"name": "Pattern",
"attributes": {
"regexp": "[0-9]+"
}
}
]
}
}
},
"view": {
"otpCodeAvailableAttempts": 2,
"msisdn": "79876543210",
"nextOtpCodePeriod": 120,
"blockedFor": 0,
"isBlocked": false
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "enter_otp_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
Пример с просроченным кодом
{
"form": {
"errors": [
{
"field": "otpCode",
"message": "otp_expired"
}
],
"name": "otpForm",
"fields": {
"otpCode": {
"constraints": [
{
"name": "NotNull"
},
{
"name": "Size",
"attributes": {
"min": 4,
"max": 4
}
},
{
"name": "Pattern",
"attributes": {
"regexp": "[0-9]+"
}
}
]
}
}
},
"view": {
"otpCodeAvailableAttempts": 2,
"msisdn": "79876543210",
"nextOtpCodePeriod": 120,
"blockedFor": 0,
"isBlocked": false
},
"serverUrl": "https://sso.rooxteam.com/sso/auth/websso",
"step": "enter_otp_form",
"execution": "dec7dacf-as2d-4345-aae5-d08410cb8f95_H4sIAAAAAAAAAN1WTWwcRRYu27GdxE5wEnYF..."
}
13.3.8. Успешное завершение цепочки
Входные данные (от сервера к виджету)
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
step |
да |
Код состояния |
всегда redirect |
location |
да |
URL для редиректа |
Пример
{
"step": "redirect",
"location": "/sso/auth/complete"
}
Выходные данные (от виджета к серверу)
Надо сделать редирект на <location>, если он есть и не пустой. Переход на него проставит куку iPlanetAuthToken с временным JWT токеном. После чего пользователь будет перенаправлен на /UI/Login, где ему проставят WebSSO куку и перенаправят на goto.
13.4. Возврат к защищаемому сервису
В виджете может быть кнопка или ссылка, по которой пользователь сможет вернуться на страницу защищаемого сервиса, который инициировал аутентификацию.
| Информация о том, отображать ли кнопку, автоматически вызывать cancel при блокировке или просто отображать сообщение, будет пробрасываться в виджет отдельным параметром, детали будут утверждены позже |
По клику на эту кнопку или ссылку должен выполняться запрос на сервер следующего вида:
| имя | обязательный | описание | констрейнты |
|---|---|---|---|
_eventId |
да |
Идентификатор действия |
cancel |
Сервер должен вернуть ответ аналогичный успешному завершению
{
"step": "redirect",
"location": "/sso/auth/complete"
}
Необходимо выполнить редирект пользователя на указанный URL.
13.5. Возможные ограничения на поля формы
| название | описание | атрибуты | описание атрибута |
|---|---|---|---|
NotNull |
Обязательность поля |
||
Size |
Длина строкового параметра |
min |
Минимальная длина |
max |
Максимальная длина |
||
Pattern |
Regexp для строкового параметра |
regexp |
Регулярное выражение |
Min |
Минимальное значение целого числового параметра |
value |
Минимальное значение |
Max |
Максимальное значение целого числового параметра |
value |
Максимальное значение |
DecimalMin |
Минимальное значение десятичного числового параметра |
value |
Минимальное значение |
DecimalMax |
Максимальное значение десятичного числового параметра |
value |
Максимальное значение |
FilteredSize |
Ограничения на номер телефона |
min |
Минимальная длина |
max |
Максимальная длина |
||
skip |
Регулярное выражение для фильтрации. Перед отправкой нужно удалять все, что ему удовлетворяет. Например, происходит очищение введенных данных от всех символов кроме цифр, дальше удалять все символы слева до первой девятки (не включая). |
13.6. Возможные коды ошибок
| код | описание | комментарий |
|---|---|---|
ip_blocked |
IP адрес, с которого пользователь обращается в WebSSO, заблокирован. |
user_blocked |
Учетная запись пользователя заблокирована. |
system_blocked |
Заблокировано приложение (client_id) |
invalid_captcha |
Введенная пользователем CAPTCHA неверная. |
|
need_captcha |
Для продолжения сценария пользователь должен ввести CAPTCHA. |
invalid_credentials |
Пользователь ввел неправильные данные учетной записи и не был аутентифицирован. |
expired_password |
Время действия пароля, введенного пользователем, истекло. Пользователь не был аутентифицирован. |
may not be null |
Поле не может быть пустым |
Ошибка валидации формы, смотреть детали в массиве ошибок на поля формы |
size must be between {min} and {max} |
Значение должно быть в заданном диапазоне |
Ошибка валидации формы, смотреть детали в массиве ошибок на поля формы |
required on {field name} |
Обязательное поле |
Ошибка валидации формы, смотреть детали в массиве ошибок на поля формы |
must match "{regexp}" |
Соответствие регулярному выражению |
Ошибка валидации формы, смотреть детали в массиве ошибок на поля формы |
too_many_wrong_code |
Превышен лимит попыток ввода OTP кода |
|
too_many_sms |
Превышен лимит попыток заказа нового OTP кода |
|
too_many_sends |
То же, что и too_many_sms, но для EMAIL и нового универсального 2FA |
|
error_sending_otp |
Транспортная ошибка доставки OTP |
|
otp-error |
Общая неклассифицируемая ошибка обработки OTP |
|
login-by-otp-disabled |
Системе в client_id запрещено проходить сценарий 2FA |
|
invalid_otp |
Введен неверный OTP код |
|
validate-otp-fail |
Введенный OTP неверный. |
otp_expired |
Время действия введенного OTP истекло. |
otp-expired |
Время действия введенного OTP истекло. |
system_error |
Общая неклассифицируемая ошибка UIDM |
|
error |
Пользователь не был аутентифицирован в результате неожиданного ответа от внешней системы. |
otp-error |
Сценарий ввода OTP завершился неуспешно. |
external-api-error |
Выполнение сценария невозможно, поскольку получен неожиданный ответ от внешней системы или внешняя система не доступна. |
external-system-bad-response |
Выполнение сценария невозможно, поскольку получен неожиданный ответ от внешней системы или внешняя система не доступна. |
msisdn-is-not-b2b |
Введенный msisdn не принадлежит реалму b2b. |
too_many_attempts |
Превышено число допустимых попыток изменения пароля. |
user-is-not-allowed |
Данному пользователю запрещено продолжать данный сценарий. |
error_password_change |
Сценарий изменения пароля не был успешно завершен. Пароль не был изменен. |
no_email_found |
Пользователь не найден или у пользователя не существует email. |
msisdn-not-exists |
Пользователя с заданным msisdn не существует. |
principal-not-exists |
Пользователь не существует. |
no-principal-found |
Пользователь не существует. |
user-not-found |
Пользователь не существует. |
login-exists |
Невозможно зарегестрировать пользователя с заданным login, поскольку пользователь с заданным login уже существует. |
login_already_exists |
Невозможно изменить login пользователя на заданный, поскольку пользователь с заданным login уже существует. |
email-exists |
Пользователь с заданным email уже существует. |
user-exists |
Невозможно зарегестрировать пользователя с заданными msisdn или email или login, поскольку пользователь с такими параметрами уже существует. |
email_verification_failed |
Невозможно подтвердить email. |
13.7. Дополнительные условия
Для работы цепочки аутентификации нужно при каждом запросе передавать cookie JSESSIONID. Если cookie отсутствует или истекло время сессии, вернется ошибка HTTP 400 вида:
{
"error": {
"code": 400,
"message": "No flow execution could be found with key 'e2s2'"
}
}
Если в запросе указан execution с валидным идентификатором e но невалидным шагом s, вернется ошибка HTTP 400 вида:
{
"error": {
"code": 400,
"message": "No flow execution snapshot could be found with id '4'; perhaps the snapshot has been removed?"
}
}
13.8. Алгоритм формирования socialData
Параметр socialData это данные от JS API соцсети, сериализованные как url-параметры и закодированные в base64.
13.8.1. Пример функции сериализации
function encodeSocialParams(params) {
var result = "";
for (var param in params) {
result += param + "=" + params[param] + "&"
}
result = result.substr(0, result.length - 1);
return encodeURIComponent(result);
}
13.8.2. Пример получения socialData для Vkontakte
function vkontakteAuth(response) {
if (response.session) {
var socialData = base64.encode(encodeSocialParams(response.session), false, true);
var loginType = 'WEBSITE';
$('#auth_method').val('vkontakte');
$('#_eventId').val('vkontakte');
$('#socialData').val(socialData);
$('#loginType').val(loginType);
$('#authForm').attr('target', '_top');
$('#authForm').submit();
}
}
function loginVK() {
VK.Auth.login(vkontakteAuth);
}
13.8.3. Пример получения socialData для Одноклассники
function loginOK() {
//функция должна открыть окно логина в одноклассники (state можно не передавать)
// https://connect.ok.ru/oauth/authorize?client_id={clientId}&scope={scope}&response_type={{response_type}}&redirect_uri={redirectUri}&layout={layout}&state={state}
//и обработать
//302 редирект в этом окне на зарегистрированный для приложения redirect uri {com.rooxteam.sso.endpoint}/ok_callback.jsp/?code={.....}&state={...}
// после подтверждения юзером разрешения на доступ SSO plugin к профилю
//закодировать параметры code и state (если есть) в base64 для получения socialData
//закрыть окно логина в Одноклассники
// заполнить и отправить форму перехода #authForm
$('#auth_method').val('odnoklassniki');
$('#_eventId').val('odnoklassniki');
$('#socialData').val(socialData);
$('#loginType').val('WEBSITE');
$('#authForm').attr('target', '_top');
$('#authForm').submit();
}









