Single Sign-On. Технология единого входа
Есть сайт где нужно авторизоваться, и система авторизации (SSO). Схема работает следующим образом:
-
Посылается аякс запрос в систему авторизации с проверкой авторизации.
URL: https://bus-sso-gateway/api/org.sso/User/core.auth/check - Возвращается ответ. ERROR_OK пользователь авторизован. ERROR_AUTH - пользователь не авторизован.
-
Если пользователь авторизован, то в браузере создается уникальный временный токен для авторизации. Он отправляется заппрос на сайт во внешнюю шину.
URL: https://bus-site-gateway/api/org.sso/User/core.auth/signAuthTmpToken. Сайт подписывает временный токен своим приватным ключом. Токен создается на определенное время. - Сайт отвечает браузеру подписанным временным токеном.
-
Посылается аякс запрос во внешнюю шину системы авторизации.
SSO проверяет токен публичным ключом сайта. Это токен устанавливает временный токен для сессии для конкретного сайта.
URL: https://bus-sso-gateway/api/org.sso/User/core.auth/setAuthTmpToken. -
Браузер посылает запрос сайту для авторизации через токен.
URL: https://bus-site-gateway/api/org.sso/User/core.auth/authFromTmpToken. -
Сайт посылает системный запрос в SSO. Система SSO, проверяет временный токен и создает JWT токен. и возвращает его.
URL: https://bus-sso-gateway/bus/org.sso/User/core.auth/createJWTFromTmpToken. - Сайт устанавливает JWT куки и возвращает их браузеру.
Формат JWT токенов
{
"c": "", /* created jwt unix time */
"e": "", /* expire jwt unix time */
"u": "", /* user login */
"i": "", /* user_id > 0 */
"s": "", /* session_id */
},
Описание API
Вход в систему
POST: https://sso.example/api/sso/login/
{
"method": "login",
"login": "",
"password": "",
}
Ответ:
{
"result": {
"jwt_data": [
"user_id": "",
"session_id": "",
"login": "",
],
"jwt_string": "",
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Ответом на этот запрос будет установлена в куках jwt.
Выход из системы
POST: https://sso.example/api/sso/logout/
В запросе в куки нужно передать jwt токен
Ответ:
{
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Происходит удаление сессии из базы данных.
Проверка авторизации
URL: https://sso.example/api/sso/check_auth/
Ответ если пользователь авторизован:
{
"result": {
"login_hash": "",
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Пользователь неавторизован:
{
"result": {
"login_hash": "",
},
"error": {
"code": -1,
"message": "User not auth",
"name": "Core.Exceptions.NotAuthException"
}
}
Подпись временного токена авторизации
Фронтенд отправляет на бэкенд запрос с временным токеном.
POST: https://app.example/api/sso/sign_tmp_token/
{
"tmp_token": "",
}
Ответ:
Возвращает id проекта, токен и подпись этого токена.
{
"result": {
"project_id": "",
"tmp_token": "",
"sign": <base64 of sign>,
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Установка временного токена авторизации в sso
Фронтенд отправляет в sso подписанный бэкендом временный токен. JWT передается на sso в куках запроса. Это запрос выполняется, если пользователь авторизован на SSO.
Проект SSO проверяет текущую куку jwt, узнает user_id и в базе для этого пользователя для конретного проекта записывает этот временный токен.
POST: https://sso.example/api/sso/set_tmp_token/
{
"project_id": "",
"tmp_token": <string of token>,
"sign": <base64 of sign>,
}
Ответ:
{
"result": {
"project_id": "",
"tmp_token": "",
"sign": <base64 of sign>,
"expire": DateTime,
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Создание JWT токена через временный tmp токен
Фронтенд отправляет запрос на бэкенд. POST: https://app.example/api/sso/auth_tmp_token/
Бэкенд отправляет запрос на sso. POST: https://sso.example/api/sso/auth_tmp_token/
sso читает временный токен, проверяет его подпись, находит временный токен в базе, узнает ID пользователя и создает JWT токен и возвращает его бэкенду, а тот передает его на фронтенд.
{
"project_id": "",
"tmp_token": "",
"sign": <base64 of sign>,
}
Ответ:
{
"result": {
"jwt_data": [
"user_id": "",
"session_id": "",
"login": "",
],
"jwt_string": "",
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Обновление JWT токена
Фронтенд отправляет запрос на бэкенд. В куках запроса передается jwt токен. POST: https://app.example/api/sso/update_jwt_token/
Бэкенд проверяет цифровую подпись токена, и если она корректна, то отправляет запрос на sso. POST: https://sso.example/api/sso/update_jwt_token/
SSO обновляет дату окончания действия токена и пересоздает его. Ответом на этот запрос будет установлена в куках новая jwt.
Ответ:
{
"result": {
"jwt_data": [
"user_id": "",
"session_id": "",
"login": "",
],
"jwt_string": "",
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}
Запрос на получения списка полномочий
Запрос может быть послан либо в бэкенд, либо в sso
URL: https://sso.example/api/sso/get_permissions/
URL: https://app.example/api/sso/get_permissions/
JWT передается в куках запроса.
Ответ:
{
"result": {
"user_id": "",
"session_id": "",
"login": "",
"permissions":
[
{
"project_id": "project_name",
"permissions":
[
"permission1",
"permission2",
"permission3",
"permission4",
"permission5",
],
"layers":
{
[
"layer_id": "номер слоя",
"permissions":
[
"permission1",
"permission2",
"permission3",
"permission4",
]
]
},
}
]
},
"error": {
"code": 1,
"message": "",
"name": ""
}
}