# Dex Demo Application Демонстрационное приложение для аутентификации через DexAuthenticator в Kubernetes кластере с Deckhouse. ![preview](preview.png) ## Описание Простое приложение, демонстрирующее интеграцию с DexAuthenticator: - **Backend (Python/FastAPI)**: Валидирует JWT токены, получает данные пользователя из PostgreSQL - **Frontend (React/Vite)**: Отображает информацию о пользователе и доступные ресурсы на основе ролей - **PostgreSQL**: Хранит пользователей, роли и доступные ссылки - **DexAuthenticator**: Обеспечивает аутентификацию через Dex ## Работа приложения 1. Пользователь открывает `https://python-navigator-demo.127.0.0.1.sslip.io` 2. Ingress перенаправляет на DexAuthenticator для аутентификации 3. Если не аутентифицирован происходит редирект на Dex (HTTP 302) для входа 4. Если не аутентифицирован в Dex происходит редирект на Blitz IdP (HTTP 302) для входа 5. После аутентификации в Blitz IdP → возврат в Dex 6. После успешной аутентификации Dex возвращает токен в DexAuthenticator 7. DexAuthenticator устанавливает заголовки (`X-Auth-Request-Email`,`X-Auth-Request-User`, `Authorization`) и cookie 8. После успешной аутентификации Frontend загружается 9. Frontend делает запрос к `/api/user-info` 10. DexAuthenticator устанавливает заголовки (`X-Auth-Request-Email`,`X-Auth-Request-User`, `Authorization`) и cookie 11. Backend: - Валидирует JWT токен из заголовка `Authorization` - Извлекает email/id пользователя - Получает данные из PostgreSQL - Возвращает информацию о пользователе и доступных ресурсах 12. Frontend отображает информацию о пользователе и доступные ресурсы ![Диаграмма последовательности](sequenceDiagram.png) ## Архитектура ``` ┌─────────────┐ │ Browser │ └─────┬───────┘ │ ▼ ┌─────────────────────────────────────┐ │ Ingress + DexAuthenticator │ │ (аутентификация через Dex) │ └─────┬───────────────────────────────┘ │ ├──────────► Frontend (React) │ │ │ ▼ └──────────► Backend (FastAPI) │ ▼ PostgreSQL ``` ## Предварительные требования - Kubernetes кластер с Deckhouse - Настроенный Dex по адресу `https://dex.127.0.0.1.sslip.io` - Docker - kubectl - make ## Быстрый старт ### 1. Сборка Docker образов ```bash # Собрать все образы make build-all # Или по отдельности: make build-backend make build-frontend ``` ### 2. Развертывание в Kubernetes ```bash make deploy ``` Приложение будет доступно по адресу: `https://python-navigator-demo.127.0.0.1.sslip.io` #### Финальная архитектура в Kubernetes: ```mermaid flowchart A["python-navigator-demo.127.0.0.1.sslip.io"] --> B["Единый Ingress + DexAuthenticator
(аутентификация)"] B --> C["Frontend Service"] B --> D["DexAuthenticator Service"] B --> E["Backend Service"] C --> F["Frontend Pods"] D --> G["DexAuthenticator Pods"] E --> H["Backend Pods"] H --> I["PostgreSQL Service"] classDef ingress fill:#e1f5fe classDef service fill:#f3e5f5 classDef pod fill:#e8f5e8 classDef database fill:#fff3e0 class A,B ingress class C,D,E service class F,G,H pod class I database ``` ### 3. Удаление приложения ```bash make undeploy # Или полная очистка (включая Docker образы): make clean ``` ## Структура проекта ``` . ├── backend/ # Python бэкенд │ ├── main.py # FastAPI приложение │ ├── requirements.txt # Python зависимости │ └── Dockerfile # Docker образ ├── frontend/ # React фронтенд │ ├── src/ │ │ ├── App.jsx # Главный компонент │ │ └── App.css # Стили │ ├── nginx.conf # Nginx конфигурация │ └── Dockerfile # Docker образ ├── db/ # База данных │ └── init.sql # SQL скрипт инициализации ├── k8s/ # Kubernetes манифесты │ ├── namespace.yaml │ ├── postgres.yaml │ ├── backend.yaml │ ├── frontend.yaml │ ├── dex-authenticator.yaml │ └── ingress.yaml ├── Makefile # Команды для сборки и развертывания └── README.md # Документация ``` ## Компоненты ### Backend (FastAPI) **Эндпоинты:** - `GET /api/health` - Проверка здоровья сервиса - `GET /api/user-info` - Получение информации о пользователе **Функциональность:** - Валидация JWT токенов от Dex (проверка подписи, issuer, exp) - Извлечение email пользователя из токена или заголовков - Получение данных пользователя из PostgreSQL (организация, полное имя) - Получение ролей пользователя - Получение доступных ссылок на основе ролей ### Frontend (React + Vite) **Функциональность:** - Отображение информации о пользователе - Список ролей - Доступные ресурсы на основе ролей пользователя - Никакой логики аутентификации (вся аутентификация на стороне DexAuthenticator) ### База данных (PostgreSQL) **Схема:** - `organizations` - Организации - `users` - Пользователи - `roles` - Роли - `user_roles` - Связь пользователей и ролей - `links` - Доступные ссылки - `role_links` - Связь ролей и ссылок ### Тестовые данные По умолчанию в БД загружаются следующие тестовые пользователи: 1. **admin@example.com** (Иван Администраторов) - Роли: admin, developer - Организация: Acme Corporation - Доступ: ко всем ресурсам 2. **developer@example.com** (Мария Разработчикова) - Роли: developer, user - Организация: Tech Innovators Inc - Доступ: технические ресурсы (CI/CD, Git, Docs, Wiki) 3. **user@example.com** (Петр Пользователев) - Роли: user - Организация: Global Solutions Ltd - Доступ: только база знаний 4. **manager@example.com** (Анна Менеджерова) - Роли: manager, user - Организация: Acme Corporation - Доступ: управленческие ресурсы (Проекты, Отчеты, Wiki) **Важно:** Убедитесь, что эти email совпадают с пользователями в вашем Dex, или измените данные в `db/init.sql` ## Конфигурация ### Backend переменные окружения - `DB_HOST` - Хост PostgreSQL (по умолчанию: `postgres`) - `DB_PORT` - Порт PostgreSQL (по умолчанию: `5432`) - `DB_NAME` - Имя БД (по умолчанию: `dexdemo`) - `DB_USER` - Пользователь БД (по умолчанию: `dexdemo`) - `DB_PASSWORD` - Пароль БД - `DEX_ISSUER` - URL Dex issuer (по умолчанию: `https://dex.127.0.0.1.sslip.io/`) ### DexAuthenticator Настройки в `k8s/dex-authenticator.yaml`: - `applicationDomain` - Домен приложения - `sendAuthorizationHeader` - Отправка заголовка Authorization с JWT - `keepUsersLoggedInFor` - Время сессии (24h) ## Разработка ### Локальная разработка backend ```bash cd backend python -m venv venv source venv/bin/activate pip install -r requirements.txt export DB_HOST=localhost export DEX_ISSUER=https://dex.127.0.0.1.sslip.io/ python main.py ``` Для удобной локальной разработки без настройки OIDC/Dex есть режим разработки. ```bash export INSECURE_DEV_MODE=true export INSECURE_DEV_EMAIL=developer@example.com ``` #### Что происходит в режиме разработки - **Отключается проверка JWT токенов** - не требуется настройка Dex или OIDC - **Используется фиксированный email** - задается через переменную `INSECURE_DEV_EMAIL` - **Логирование** - в консоли будет выводиться сообщение о том, какой email используется **Никогда не используйте INSECURE_DEV_MODE=true в продакшене!** Это отключает всю аутентификацию. ### Локальная разработка frontend ```bash cd frontend npm install npm run dev ``` Frontend будет доступен на `http://localhost:5173` с проксированием API на `http://localhost:8000` ### Ошибка "User not found in database" Убедитесь, что email пользователя из Dex совпадает с email в таблице `users` в PostgreSQL. ### JWT валидация не работает Проверьте: 1. Доступность Dex JWKS endpoint: `https://dex.127.0.0.1.sslip.io/keys` 2. Переменную окружения `DEX_ISSUER` в backend 3. Логи backend для деталей ошибки ## Дополнительная настройка ### Изменение тестовых пользователей Отредактируйте `db/init.sql` или `k8s/postgres.yaml` (ConfigMap `postgres-init`), затем: ```bash kubectl delete pod -n navigator-demo -l app=postgres ``` ### Использование собственного домена Измените `applicationDomain` в `k8s/dex-authenticator.yaml` и `host` в `k8s/ingress.yaml` ### Production deployment Для production окружения: 1. Используйте secrets для паролей БД 3. Включите TLS сертификаты 4. Настройте resource limits 5. Добавьте HorizontalPodAutoscaler 6. Используйте внешний PostgreSQL