Регистрация mm в каталоге приложений, permissions mm:*, target-app и docs. Co-authored-by: Cursor <cursoragent@cursor.com>
3.8 KiB
Интеграция auth-portal ↔ MikrotikManager
Единый вход: пользователь логинится на auth-portal, получает JWT, переходит в MikrotikManager с токеном в URL fragment. Backend MM проверяет JWT и права mm:*.
Архитектура
Browser → MikrotikManager UI (нет token)
→ redirect AUTH_PORTAL_URL/?return_to=…/auth/callback
→ login
→ redirect return_to#access_token=…
→ MM /auth/callback сохраняет token (mmapp_token)
→ API Authorization: Bearer …
Общий секрет: JWT_SECRET / AUTH_JWT_SECRET (HS256). Issuer: ISSUER / AUTH_ISSUER.
App id в портале: mm (каталог permissions).
Локальный запуск
1. auth-portal
cd auth-portal
pnpm install
# JWT_SECRET=dev-secret-change-me
# RETURN_TO_ALLOWLIST=.shnt.top,localhost,http://localhost:3000
pnpm --filter @authportal/api dev # :8080
pnpm --filter web dev # :5175
Bootstrap: admin@shnt.top / admin. В админке выдайте app mm и permissions mm:*.
2. MikrotikManager
cd MikrotikManager
npm install
Backend backend/.env:
AUTH_REQUIRED=true
AUTH_JWT_SECRET=dev-secret-change-me
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=http://localhost:5175
CORS_ORIGIN=http://localhost:3000
Frontend: NEXT_PUBLIC_AUTH_PORTAL_URL=http://localhost:5175 (или runtime GET /api/auth/config через proxy).
npm --prefix backend run dev
npm run dev
Откройте http://localhost:3000 → редирект на portal → после логина NavUser показывает имя/email.
Permissions ↔ API / UI
Иерархия: admin ⊃ write ⊃ read в рамках одной секции.
| Permission | API (prefix) | UI |
|---|---|---|
mm:dashboard:read |
sidebar-counts, events (GET) | /dashboard |
mm:servers:read / write |
/api/servers* |
/servers |
mm:filters:read / write |
/api/filters* |
/filters, GRE |
mm:bgp:read / write |
/api/bgp* |
BGP |
mm:uptime:read / write |
/api/uptime* |
/uptime |
mm:traffic:read / write |
/api/traffic* |
/traffic |
mm:alerts:read / write |
/api/alerts* |
/alerts |
mm:backups:read / write |
/api/backups* |
/backups |
mm:certificates:read / write |
/api/certificates* |
certificates |
mm:network:read / write |
/api/network*, OSPF, recursive, probes |
network |
mm:settings:admin |
/api/system/*, scheduler, evobgp settings |
/settings |
Без app mm в JWT apps → 403 на защищённые /api/*.
AUTH_REQUIRED=false — API открыт (dev без portal).
App Switcher
CURRENT_APP_ID = mm. Публичный конфиг: GET {AUTH_PORTAL_URL}/api/v1/app-switcher.
Logout (SSO)
Очистить mmapp_token → редирект на {AUTH_PORTAL_URL}/logout.
Production
См. общий стек CDN+MM: deploy/docker-compose.cdn-mm.yml / deploy/env.cdn-mm.example.
AUTH_REQUIRED=true
AUTH_JWT_SECRET=<тот же JWT_SECRET портала>
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=https://auth.shnt.top
CORS_ORIGIN=https://mm.shnt.top
В portal: RETURN_TO_ALLOWLIST включает https://mm.shnt.top (или .shnt.top).
Troubleshooting
| Симптом | Причина |
|---|---|
| SSO loop | разный JWT_SECRET или ISSUER |
| 403 «Нет доступа к приложению» | нет app mm у пользователя |
| 403 «Недостаточно прав» | нет нужного mm:… |
| return_to rejected | origin MM не в RETURN_TO_ALLOWLIST |