Token Exchange
Token Exchange (RFC 8693) ist ein OAuth 2.0-Erweiterungsgrant, der es einem privilegierten Dienst erlaubt, ein vorhandenes Token gegen ein neues Token einzutauschen, das entweder:
- Die Identität eines anderen Benutzers annimmt (Impersonation): Das
subim neuen Token ist der Zielbenutzer, nicht der anfragende Dienst. - Im Namen eines anderen Dienstes handelt (Delegation): Das
subim neuen Token ist dasselbe, aber deract-Claim zeichnet den delegierenden Dienst auf.
| Impersonation | Delegation | |
|---|---|---|
| sub | Ändert sich zum Zielbenutzer | Bleibt beim ursprünglichen Subjekt |
| act | Original-Actor (Admin, der imitiert) | Delegierender Dienst |
| Typischer Anwendungsfall | Admin übernimmt Benutzersitzung für Support | Frontend-Dienst handelt im Namen des Benutzers gegenüber Backend |
| Berechtigung | impersonate:users | delegate:tokens |
Impersonation-Token-Struktur
{
"sub": "target-user-id",
"email": "[email protected]",
"roles": ["member"],
"act": {
"sub": "admin-user-id",
"email": "[email protected]"
},
"iat": 1700000000,
"exp": 1700003600
}Das act-Claim zeigt immer die Person oder den Dienst, der tatsächlich handelt — wesentlich für Audit-Logs.
Delegations-Token-Struktur
{
"sub": "original-user-id",
"aud": "backend-service",
"act": {
"sub": "frontend-service-client-id"
},
"scope": "read:invoices",
"iat": 1700000000,
"exp": 1700003600
}Einrichten
- Öffne die Auris Console → Applications → deine Anwendung.
- Navigiere zu Advanced → Token Exchange und aktiviere es.
- Konfiguriere, welche Exchange-Typen erlaubt sind: Impersonation, Delegation oder beide.
- Weise der aufrufenden Client-Anwendung die erforderlichen Berechtigungen zu:
- Für Impersonation:
impersonate:users - Für Delegation:
delegate:tokens
- Für Impersonation:
Token Exchange erfordert einen vertraulichen Client (confidential client) mit einem client_secret. Öffentliche Clients (z.B. Single-Page-Apps ohne Backend) können keine Token-Exchanges durchführen.
Verwendung
JavaScript SDK
import { AurisManagementClient } from '@auris/js'
const mgmt = new AurisManagementClient({
domain: process.env.AURIS_DOMAIN,
clientId: process.env.AURIS_CLIENT_ID,
clientSecret: process.env.AURIS_CLIENT_SECRET,
})
// Impersonation — handeln als target-user
const impersonatedToken = await mgmt.auth.exchangeToken({
subjectToken: existingAccessToken,
subjectTokenType: 'urn:ietf:params:oauth:token-type:access_token',
requestedTokenType: 'urn:ietf:params:oauth:token-type:access_token',
requestedSubject: 'user-id-to-impersonate',
audience: 'https://api.yourdomain.com',
scope: 'read:invoices view:profile',
})
console.log(impersonatedToken.access_token) // Token mit sub = Zielbenutzer
// Delegation — im Auftrag des ursprünglichen Benutzers gegenüber einem Backend handeln
const delegatedToken = await mgmt.auth.exchangeToken({
subjectToken: userAccessToken,
subjectTokenType: 'urn:ietf:params:oauth:token-type:access_token',
requestedTokenType: 'urn:ietf:params:oauth:token-type:access_token',
audience: 'backend-service',
scope: 'read:invoices', // Scope kann nur eingeschränkt werden
})Anfrage-Parameter
| Parameter | Pflicht | Beschreibung |
|---|---|---|
grant_type | ✅ | Muss urn:ietf:params:oauth:grant-type:token-exchange sein |
client_id | ✅ | Client-ID der anfragenden Anwendung |
client_secret | ✅ | Client-Secret (vertrauliche Clients erforderlich) |
subject_token | ✅ | Das einzutauschende Token |
subject_token_type | ✅ | Typ des subject_token (normalerweise urn:ietf:params:oauth:token-type:access_token) |
requested_token_type | Typ des angeforderten Tokens (Standard: access_token) | |
requested_subject | Bei Impersonation: Benutzer-ID des Ziel-Subjekts | |
audience | Beabsichtigte Ziel-Audience des neuen Tokens | |
scope | Angeforderter Scope; kann nur eingeschränkt, nicht erweitert werden |
Verschachtelte Delegationsketten
Der act-Claim kann verschachtelt werden, um mehrstufige Delegation aufzuzeichnen:
{
"sub": "user-123",
"act": {
"sub": "api-gateway-client-id",
"act": {
"sub": "frontend-service-client-id"
}
}
}Dies zeigt: frontend-service delegierte an api-gateway, der nun im Namen von user-123 handelt. Jede Ebene ist im Token vollständig nachvollziehbar.
Ausgetauschte Tokens validieren
Im Backend solltest du ausgetauschte Tokens identifizieren und entsprechend handeln:
import { verifyToken } from '@auris/node'
const payload = await verifyToken(accessToken, {
domain: process.env.AURIS_DOMAIN!,
audience: process.env.AURIS_AUDIENCE!,
})
if (payload.act) {
// Dieses Token ist das Ergebnis eines Token Exchange
const effectiveSubject = payload.sub // Wer handelt
const originalActor = payload.act.sub // Wer hat initiiert
// Für Audit-Logs immer beide protokollieren
logger.info('Token Exchange erkannt', {
effectiveSubject,
originalActor,
action: req.method + ' ' + req.path,
})
// Hochriskante destruktive Operationen für imitierte Tokens blockieren
if (isDestructiveOperation(req) && effectiveSubject !== originalActor) {
return res.status(403).json({ error: 'Destruktive Operationen durch Impersonation nicht erlaubt' })
}
}Sicherheitshinweise
- Scope kann nur eingeschränkt werden: Ein ausgetauschtes Token darf nie einen breiteren Scope haben als das Ursprungs-Token.
- Vertraulicher Client erforderlich: Öffentliche Clients können keinen Token Exchange durchführen.
- 1-Stunden-Lebensdauer: Ausgetauschte Tokens laufen standardmäßig nach 1 Stunde ab, unabhängig von der Ursprungs-Token-Lebensdauer.
- Vollständiges Audit-Logging: Alle Token-Exchanges werden im Auris Audit-Log protokolliert — wer hat für wen getauscht, wann und für welchen Scope.
- Impersonation-Schutz: Verwende
act-Claim-Prüfungen in deiner API, um imitierte Tokens von regulären Tokens zu unterscheiden.
API-Referenz
/api/auth/tokenToken-Exchange-Grant-Endpunkt. Akzeptiert grant_type=urn:ietf:params:oauth:grant-type:token-exchange mit den oben genannten Parametern.
/api/oauth/token-exchangesRequires: view:token_exchangesAuflisten aller Token-Exchanges, die im Tenant durchgeführt wurden. Gibt paginierte Exchange-Datensätze mit Actor, Subject, Audience, Scope und Zeitstempel zurück.
Berechtigungen
| Berechtigung | Beschreibung |
|---|---|
impersonate:users | Erlaubt dem Dienst, als ein anderer Benutzer zu imitieren (requested_subject) |
delegate:tokens | Erlaubt dem Dienst, Delegation-Token-Exchanges durchzuführen |
view:token_exchanges | Erlaubt das Auflisten von Token-Exchange-Protokollen in der Management API |
manage:applications | Erforderlich, um Token Exchange in der Anwendungskonfiguration zu aktivieren/deaktivieren |
Verwandte Anleitungen
- M2M Client Credentials — Service-Tokens, die für Token Exchange verwendet werden
- Rollen & Berechtigungen (RBAC) — Berechtigungen für Token Exchange zuweisen
- Audit Logs — Token-Exchange-Aktivitäten überwachen