Tmavý režim
JWT Provideři
Konfigurace
JWT provideři se konfigurují v config/default.yaml (nebo production.yaml) pod klíčem token.jwt:
yaml
token:
keyRefreshIntervalMinutes: 60 # Interval refreshe JWKS klíčů
jwt:
- provider: zitadel
baseUrl: http://zitadel:8080
jwk: /oauth/v2/keys
issuer: http://localhost:8080
hostOverride: localhost # Volitelné: přepíše host při fetch klíčů
- provider: amotion
baseUrl: https://auth-dev.am-space.cz
jwk: /.well-known/jwks.json
issuer: https://auth-dev.am-space.cz
- provider: microsoft
baseUrl: https://login.microsoftonline.com
jwk: /common/discovery/v2.0/keys
issuer: https://login.microsoftonline.com/{tenantId}/v2.0
- provider: google
baseUrl: https://accounts.google.com
jwk: /oauth/v2/certs
issuer: https://accounts.google.comZitadel (primární provider)
Zitadel je self-hosted OIDC provider, který zajišťuje primární autentizaci pro všechny Atrea aplikace.
Speciální claims
Zitadel přidává do JWT tokenu navíc:
| Claim | Popis |
|---|---|
urn:zitadel:iam:user:resourceowner:id | ID organizace uživatele |
urn:zitadel:iam:org:project:roles | Role uživatele v projektech |
Organizace
Při přihlášení přes Zitadel je z tokenu extrahováno orgId. To umožňuje mapování Zitadel organizací na aplikace v Atrea User API (viz config.zitadel.orgToApp).
Login flow (PKCE)
1. GET /api/zitadel/login?client_id=<clientId>
→ Redirect na Zitadel login stránku
2. Uživatel se přihlásí v Zitadel
3. GET /api/zitadel/callback?code=<authCode>&state=<state>
→ Výměna auth code za access token
→ Redirect s tokenem
4. Frontend uloží token a používá ho v Bearer headeruWebhoky
Zitadel posílá webhooky při událostech uživatele:
| Událost | Akce v API |
|---|---|
user.created | Vytvoří uživatele v DB (pokud neexistuje) |
user.deactivated | Deaktivuje uživatele (active = false) |
user.reactivated | Aktivuje uživatele (active = true) |
user.removed | Smaže uživatele z DB |
Webhook endpoint: POST /api/zitadel/webhook
Autentizace: X-Webhook-Secret header
Amotion
Alternativní OAuth2/OIDC server. Konfigurace je standardní JWKS endpoint.
Email extrahován z claimu email nebo preferred_username.
Microsoft (Azure AD)
Podporuje Microsoft pracovní/školní účty (Azure Active Directory).
Email je extrahován z:
emailclaimpreferred_usernameclaimupnclaim (User Principal Name)
Tenant
Použijte /common/ pro multi-tenant nebo specifický tenant ID pro single-tenant nasazení.
Google
Podporuje Google účty (Gmail, Workspace).
Email extrahován ze standardního email claimu.
Jak probíhá verifikace
typescript
// JWTService — zjednodušeně
async verifyToken(token: string): Promise<DecodedToken> {
for (const provider of this.providers) {
try {
const decoded = jwt.verify(token, provider.keys, {
algorithms: ['RS256', 'RS384', 'RS512'],
issuer: provider.issuer,
});
return { ...decoded, provider: provider.name };
} catch {
// Zkusí další provider
}
}
throw new ApiException(401, 'Invalid token');
}Tokenem projdou všichni provideři v pořadí konfigurace. První úspěšná verifikace vyhrává.
Přidání nového providera
- Přidejte konfiguraci do
config/default.yaml:
yaml
token:
jwt:
- provider: muj-provider
baseUrl: https://auth.moje-firma.cz
jwk: /.well-known/jwks.json
issuer: https://auth.moje-firma.czUjistěte se, že provider vydává JWT s
emailclaimem nebo jiným, ze kterého lze email extrahovat.Restartujte API — klíče se načtou při startu.
Troubleshooting
Token is invalid
- Ověřte, že
issuerv konfiguraci odpovídáissclaimu v tokenu - Ověřte, že JWKS endpoint je dostupný ze serveru
- Zkontrolujte expiraci tokenu (
expclaim)
JWKS fetch failed
- Zkontrolujte dostupnost
baseUrl + jwkendpointu - Pro Zitadel v Dockeru: ujistěte se, že
zitadelhostname je resolvovatelný - Použijte
hostOverridepokud se liší interní a externí hostname
Email extraction failed
- Zkontrolujte, které claims váš provider vydává
- Přidejte logiku extrakce do
JWTService.extractEmail()pokud používáte nestandartní claim