Files
ipwhitelist-app/docs/keycloak-auth-reference.md
T

185 lines
6.4 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.
# Keycloak Auth Reference — консолидированная справка
> Обновлено: 2026-06-02
> Файл-ориентир. Править по мере уточнения у DevOps и продвижения проекта.
---
## 1. Keycloak-эндпоинты
Realm: **`cloud`** на `keycloak.nubes.ru`
| Назначение | URL |
|---|---|
| Authorization | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/auth` |
| Token exchange | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/token` |
| JWKS (сертификаты) | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs` |
| Logout | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/logout` |
---
## 2. Зарегистрированное приложение (OAuth client)
`client_id` — выдаётся DevOps при регистрации приложения в Keycloak.
---
## 3. Схема аутентификации: Authorization Code Flow
```
1. Браузер → /login (приложение)
2. Приложение → 302 → Keycloak /auth?client_id=...&scope=openid&redirect_uri=...&state=...
3. Пользователь вводит логин/пароль в Keycloak
4. Пользователь вводит OTP (MFA)
5. Keycloak → 302 → /callback?code=...&state=...
6. Приложение → POST /token (code → access_token + refresh_token + id_token)
7. Валидация JWT через JWKS (RS256)
8. Извлечение claims → req.user → сессия
```
---
## 4. Получение токена через API Gateway (альтернативный путь)
Если в инфраструктуре есть API Gateway, код обменивается не напрямую в Keycloak, а через него:
```
POST <url API Gateway>/token
Content-Type: application/json
Body: {"code": "<authorization_code>"}
```
---
## 5. JWT-токены
### 5.1. Пример структуры JWT (deprecated)
```
iss: https://<issuer>/...
aud: <audience>
sub: <email>
name: <ФИО пользователя>
email: <email пользователя>
exp: <timestamp>
scope: openid
token_type: Bearer
```
> ⚠️ `ClientID` может отсутствовать — зависит от issuer'а.
### 5.2. Пример токена
| Поле | Значение |
|---|---|
| `iss` | `auth-api` |
| `ClientID` | `WZ01325` |
| `company_id` | `<uuid>` |
| `company_name` | Название компании |
| `login` | `user@example.com` |
| `email` | `user@example.com` |
### 5.3. Целевой формат токена (из ТЗ)
| Claim | Назначение |
|---|---|
| `ClientID` | Идентификатор компании (WZ-номер) |
| `company_id` | UUID компании |
| `company_name` | Название компании |
| `email` | Email пользователя (для аудита) |
| `groups` | ? (пока null) |
| `roles` | ? (пока null) |
---
## 6. Роли
| Роль | ClientID | Права |
|---|---|---|
| **Администратор** | `WZ01112` | Все записи, просмотр аудита, экспорт |
| **Клиент** | любой другой WZ-номер | Только свои записи |
> Как именно ClientID попадает в токен — через группы Keycloak или маппер — **требует уточнения у DevOps**.
---
## 7. Реализация в коде
### `src/auth.js` — два режима
| Режим | Условие | Как работает |
|---|---|---|
| **OIDC** | `KC_CLIENT_ID` + `KC_CLIENT_SECRET` заданы | Authorization Code Flow, JWKS-валидация |
| **Mock** | `KC_CLIENT_ID` пусто | Локальная RSA-пара, JWT из `MOCK_USERS` |
### `src/config.js` — Mock-пользователи
```javascript
MOCK_USERS = [
{ clientId: 'WZ01325', companyName: 'Тест', email: 'tazet@narod.ru' },
{ clientId: 'WZ01112', companyName: 'Нубес', email: 'admin@nubes.ru' }
]
```
### Два слоя аутентификации
| Слой | Механизм | Где |
|---|---|---|
| **UI (EJS)** | Session cookie + PostgreSQL session store | `/`, `/admin`, `/entries` |
| **REST API** | Bearer JWT (всегда проверяется явно) | `/api/v1/*` |
### Dev-backdoor
- `DEV_MODE=true` или `DEV_SECRET``/dev-login` — выбор любого пользователя в обход OIDC/mock
---
## 8. Переменные окружения
```env
# Auth
DEV_MODE=true
JWT_ISSUER=mock-auth-api
ADMIN_CLIENT_ID=WZ01112
# OIDC (production)
KC_BASE_URL=https://keycloak.nubes.ru/realms/cloud
KC_CLIENT_ID=
KC_CLIENT_SECRET=
APP_URL=http://localhost:3000
# Session
SESSION_SECRET=<обязателен в prod>
```
---
## 9. Открытые вопросы (к DevOps)
| # | Вопрос | Статус |
|---|---|---|
| 1 | Где брать `client_id` и `client_secret` для регистрации приложения в Keycloak? | 🔴 |
| 2 | Какой URL JWKS? `auth-api` или `keycloak.nubes.ru`? | 🔴 |
| 3 | Когда заполняются `claims.groups` и `claims.roles`? (пока null) | 🔴 |
| 4 | Как выглядит токен, если у пользователя несколько компаний? Массив `ClientID`? | 🔴 |
| 5 | Есть ли в Keycloak понятие admin-роли? В каком claim? | 🔴 |
| 6 | Redirect URI: `https://white.nodejsk8s.dev.nubes.ru/callback` — OK? | 🔴 |
| 7 | Кто потребитель `/export`? Какие IP/подсети для allowlist? | 🔴 |
| 8 | Формат `jsonEnv` — пример правильного? | 🔴 |
---
## 10. Исходные файлы
| Файл | Содержание |
|---|---|
| `docs/ТЗ.md` | Техническое задание |
| `docs/ТЗ-реализация.md` | Карта реализации требований |
| `docs/questions-devops.md` | Вопросы к DevOps |
| `research/auth-flow.md` | Детальное исследование OIDC-flow |
| `research/payg-sso/` | CF-эталон (OAuth2 + JWT RS256) |
| `Files/token.txt` | Реальный токен из test-окружения |
| `Files/nubes_login.har` | HAR трассировка login-сессии deck-test |
| `src/auth.js` | Основной модуль аутентификации |
| `src/config.js` | Конфигурация и mock-пользователи |