АРХ - NODEDC PLATFORM: fix Authentik JWKS signing
This commit is contained in:
parent
4a10726b2e
commit
1d37acdb83
|
|
@ -6,6 +6,23 @@
|
||||||
|
|
||||||
Launcher, Plane и будущие приложения не хранят пароли пользователей и не становятся главным источником truth по логину.
|
Launcher, Plane и будущие приложения не хранят пароли пользователей и не становятся главным источником truth по логину.
|
||||||
|
|
||||||
|
## User journey
|
||||||
|
|
||||||
|
Целевой production flow:
|
||||||
|
|
||||||
|
```text
|
||||||
|
nodedc.ru marketing site
|
||||||
|
-> Войти на платформу
|
||||||
|
-> platform login
|
||||||
|
-> NODE.DC Launcher
|
||||||
|
-> application tiles
|
||||||
|
-> Task Manager / future apps
|
||||||
|
```
|
||||||
|
|
||||||
|
UI платформы не должен показывать пользователю название identity-провайдера. В пользовательских кнопках и текстах используется нейтральное "Войти", "Вход на платформу", "Сессия NODE.DC".
|
||||||
|
|
||||||
|
Прямые ссылки на приложения остаются допустимым пользовательским сценарием. Если session нет, приложение или внешний proxy/auth layer должен увести пользователя в login flow и после успешного входа вернуть к исходному приложению.
|
||||||
|
|
||||||
## Required claims
|
## Required claims
|
||||||
|
|
||||||
Минимальный normalized user object:
|
Минимальный normalized user object:
|
||||||
|
|
@ -40,16 +57,15 @@ nodedc:superadmin
|
||||||
Launcher:
|
Launcher:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
nodedc:launcher:access
|
|
||||||
nodedc:launcher:admin
|
nodedc:launcher:admin
|
||||||
nodedc:launcher:user-manager
|
nodedc:launcher:user
|
||||||
```
|
```
|
||||||
|
|
||||||
Task Manager:
|
Task Manager:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
nodedc:taskmanager:access
|
|
||||||
nodedc:taskmanager:admin
|
nodedc:taskmanager:admin
|
||||||
|
nodedc:taskmanager:user
|
||||||
```
|
```
|
||||||
|
|
||||||
Future apps:
|
Future apps:
|
||||||
|
|
@ -67,6 +83,8 @@ nodedc:dm:access
|
||||||
|
|
||||||
Отвечает на вопрос, можно ли открыть приложение.
|
Отвечает на вопрос, можно ли открыть приложение.
|
||||||
|
|
||||||
|
Launcher показывает каталог приложений как витрину, а не скрывает все недоступные плитки. Для приложения без доступа кнопка перехода отключена и отображается состояние "Нет доступа". Это важно для продаж, onboarding и понимания доступных модулей платформы.
|
||||||
|
|
||||||
Уровень 2: Launcher admin roles.
|
Уровень 2: Launcher admin roles.
|
||||||
|
|
||||||
Отвечает на вопрос, можно ли управлять пользователями, группами, app registry и audit.
|
Отвечает на вопрос, можно ли управлять пользователями, группами, app registry и audit.
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,14 @@
|
||||||
|
|
||||||
## Current local apps
|
## Current local apps
|
||||||
|
|
||||||
Launcher сейчас запускается как Vite app из:
|
Launcher сейчас запускается как Vite app + local BFF из:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher
|
/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher
|
||||||
```
|
```
|
||||||
|
|
||||||
|
В dev режиме `npm run dev` запускает BFF на `:5173`; Vite подключен как middleware. Чистый Vite режим сохранен как `npm run dev:vite`.
|
||||||
|
|
||||||
Task Manager сейчас доступен как Plane self-host runtime:
|
Task Manager сейчас доступен как Plane self-host runtime:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
@ -116,6 +118,8 @@ This creates:
|
||||||
- `NODE.DC Task Manager` application with OAuth2/OIDC provider;
|
- `NODE.DC Task Manager` application with OAuth2/OIDC provider;
|
||||||
- group bindings for application access.
|
- group bindings for application access.
|
||||||
|
|
||||||
|
OIDC providers must have a signing key. Without it Authentik returns an empty JWKS (`{}`), and Launcher callback fails token validation.
|
||||||
|
|
||||||
The script fills missing `LAUNCHER_OIDC_CLIENT_SECRET` and `PLANE_OIDC_CLIENT_SECRET` values in ignored `infra/.env`. Secrets are not committed.
|
The script fills missing `LAUNCHER_OIDC_CLIENT_SECRET` and `PLANE_OIDC_CLIENT_SECRET` values in ignored `infra/.env`. Secrets are not committed.
|
||||||
|
|
||||||
Проверка:
|
Проверка:
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from django.db import transaction
|
||||||
|
|
||||||
from authentik.common.oauth.constants import SubModes
|
from authentik.common.oauth.constants import SubModes
|
||||||
from authentik.core.models import Application, Group, User
|
from authentik.core.models import Application, Group, User
|
||||||
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
from authentik.policies.models import PolicyBinding
|
from authentik.policies.models import PolicyBinding
|
||||||
from authentik.providers.oauth2.models import (
|
from authentik.providers.oauth2.models import (
|
||||||
|
|
@ -127,6 +128,13 @@ def default_scope_mappings():
|
||||||
def ensure_provider(spec, mappings):
|
def ensure_provider(spec, mappings):
|
||||||
authorization_flow = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
authorization_flow = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
||||||
invalidation_flow = Flow.objects.get(slug="default-provider-invalidation-flow")
|
invalidation_flow = Flow.objects.get(slug="default-provider-invalidation-flow")
|
||||||
|
signing_key = (
|
||||||
|
CertificateKeyPair.objects.filter(name="authentik Self-signed Certificate").first()
|
||||||
|
or CertificateKeyPair.objects.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
if signing_key is None:
|
||||||
|
raise RuntimeError("No Authentik CertificateKeyPair exists for OIDC signing")
|
||||||
|
|
||||||
provider = OAuth2Provider.objects.filter(name=spec["provider_name"]).first()
|
provider = OAuth2Provider.objects.filter(name=spec["provider_name"]).first()
|
||||||
if provider is None:
|
if provider is None:
|
||||||
|
|
@ -146,6 +154,7 @@ def ensure_provider(spec, mappings):
|
||||||
provider.issuer_mode = IssuerMode.PER_PROVIDER
|
provider.issuer_mode = IssuerMode.PER_PROVIDER
|
||||||
provider.authorization_flow = authorization_flow
|
provider.authorization_flow = authorization_flow
|
||||||
provider.invalidation_flow = invalidation_flow
|
provider.invalidation_flow = invalidation_flow
|
||||||
|
provider.signing_key = signing_key
|
||||||
provider.save()
|
provider.save()
|
||||||
provider.property_mappings.set(mappings)
|
provider.property_mappings.set(mappings)
|
||||||
return provider
|
return provider
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue