Files
IPWhiteList/docs/auth-architecture.md
T

84 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура авторизации облачного портала
> Со слов пользователя, на основе JWT из localStorage
---
## Схема аутентификации
```
Пользователь (браузер)
Keycloak (keycloak.nubes.ru, realm=cloud)
│ Authorization Code Flow
│ client_id=deck.ngcloud.ru
│ scope=openid email
auth-api.ngcloud.ru (СОБСТВЕННЫЙ сервис)
│ Создаёт свой JWT (issuer="auth-api")
│ Подпись: RS256 (RSA)
deck.ngcloud.ru (портал)
│ Микро-фронтенды (SPA): dashboard, contracts, services, ...
│ JWT хранится в localStorage: authApiTokens.access_token
IPWhiteList (наш сервис) ← будет встроен как микро-фронтенд в портал
```
## Важное
- JWT подписывает **не Keycloak**, а **auth-api**
- Issuer: `"auth-api"`, алгоритм: `RS256`
- Для валидации нужен публичный ключ auth-api (JWKS или статический)
---
## Структура JWT (access_token)
_Из localStorage → authApiTokens → access_token_
| Поле | Тип | Значение (пример) | Назначение |
|---|---|---|---|
| `iss` | string | `"auth-api"` | Кто выпустил токен |
| `sub` | string | `"0199e325-..."` | UUID пользователя |
| `iat` | number | `1780073927` | Выпущен (Unix time) |
| `exp` | number | `1780117127` | Истекает (~12 часов) |
| `jti` | string | `"4d8d7240-..."` | Уникальный ID токена |
| `ClientID` | string | `"WZ01325"` | ID **ТЕКУЩЕЙ** компании пользователя |
| `company_id` | string (UUID) | `"3e64aac6-..."` | UUID компании |
| `company_name` | string | `"Тест"` | Название компании |
| `email` | string | `"tazet@narod.ru"` | Email (для аудита) |
| `login` | string | `"tazet@narod.ru"` | Логин |
| `firstname` | string | `"Наиль"` | Имя |
| `lastname` | string | `"Тазетдинов"` | Фамилия |
| `token_type` | string | `"access"` | Тип токена |
## Что НЕ в JWT (отдельный authData в localStorage)
_Из localStorage → authData → v_
| Поле | Значение | Где используется |
|---|---|---|
| `userInfo.isAdmin` | `false` (boolean) | ⚠️ Признак администратора |
| `profiles[]` | Массив `{company_id, company_name, is_active_profile}` | Список всех компаний пользователя |
| `roles[]` | Массив `{role_id, role_name}` | Роли пользователя |
| `permissions.can_write` | `false` | Есть ли права на запись |
---
## Открытые вопросы (нужно уточнить с командой портала)
1. **Валидация JWT.** У auth-api есть JWKS (`/.well-known/jwks.json`)? Или ключ статический? Как нашему сервису проверять подпись?
2. **isAdmin.** Флаг админа есть только в authData localStorage, но не в JWT. Как наш сервис узнает что пользователь — админ?
- Вариант A: попросить добавить `isAdmin` в JWT
- Вариант B: наш сервис ходит в auth-api за authData
- Вариант C: смотреть на `ClientID == "WZ01112"` (как в ТЗ)
3. **Список компаний.** В JWT — только одна компания. В authData.profiles — массив. Для переключателя компаний в нашем UI — откуда брать список?
- Вариант A: попросить добавить `profiles` в JWT
- Вариант B: наш сервис ходит в auth-api
4. **Как наш сервис попадает в портал?** Как микро-фронтенд (SPA) или как отдельная страница с редиректом? Куда монтироваться?