Token Exchange
Il Token Exchange (RFC 8693) consente a un client di scambiare un access token esistente con uno nuovo avente un soggetto, un’audience o degli scope diversi. Questo abilita due pattern enterprise chiave: impersonazione (agire come un altro utente) e delega (agire per conto di un utente con l’attore originale registrato).
Casi d’uso comuni:
- Un admin impersona un utente per fare debug dei problemi che sta riscontrando
- Un servizio frontend delega il token utente a un servizio backend con un’audience ristretta
- Un agente del supporto agisce per conto di un cliente con una traccia di audit completa tramite il claim
act - Un microservizio restringe un token ad ampio scope a un token con scope minimo per un servizio downstream
Impersonazione vs Delega
Il token exchange supporta due pattern distinti:
| Pattern | Il Soggetto Cambia? | Claim act | Caso d’Uso |
|---|---|---|---|
| Impersonazione | Sì — il sub del nuovo token è l’utente target | Contiene l’identità dell’attore originale | Admin che fa debug della sessione di un utente |
| Delega | No — sub rimane l’utente originale | Contiene l’identità del servizio delegante | Chiamata servizio-servizio che preserva il contesto utente |
Impersonazione
Il claim sub del token risultante viene sostituito con l’utente target. L’attore originale viene registrato nel claim act affinché l’azione sia completamente verificabile tramite audit:
{
"sub": "target-user-id",
"iss": "https://auth.tuodominio.com",
"type": "user",
"act": {
"sub": "admin-user-id",
"email": "[email protected]"
}
}Delega
Il claim sub rimane lo stesso (l’utente originale), ma un claim act registra il servizio intermedio:
{
"sub": "original-user-id",
"iss": "https://auth.tuodominio.com",
"type": "user",
"aud": "backend-service",
"act": {
"sub": "frontend-service-client-id"
}
}Configurazione nella Console
Abilita il Token Exchange
Nella Console Auris, vai su Applicazioni e seleziona l’applicazione che eseguirà gli scambi di token. Nella scheda Impostazioni, attiva Abilita Token Exchange.
Configura i Tipi di Scambio Consentiti
Seleziona quali tipi di scambio l’applicazione è autorizzata a eseguire:
| Tipo | Descrizione |
|---|---|
| Impersonazione | Scambia un token con uno che ha un soggetto diverso (richiede il permesso impersonate:users) |
| Delega | Scambia un token con uno che ha un’audience diversa (richiede il permesso delegate:tokens) |
Assegna i Permessi
Assicurati che gli utenti o gli account di servizio che eseguono il token exchange abbiano i permessi appropriati:
impersonate:users— Richiesto per gli scambi di impersonazionedelegate:tokens— Richiesto per gli scambi di delega
Questi permessi possono essere assegnati tramite i ruoli in Console → Ruoli → [Ruolo] → Permessi.
Implementazione
JavaScript
const AURIS_DOMAIN = 'https://auth.tuodominio.com'
const CLIENT_ID = 'il-tuo-client-id'
const CLIENT_SECRET = 'il-tuo-client-secret'
// Impersonazione: Admin che agisce come un utente specifico
async function impersonateUser(adminToken, targetUserId) {
const response = await fetch(`${AURIS_DOMAIN}/api/auth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: adminToken,
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',
requested_subject: targetUserId,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
}),
})
if (!response.ok) {
const error = await response.json()
throw new Error(`Token exchange fallito: ${error.error_description}`)
}
return await response.json()
// { access_token: "...", token_type: "Bearer", expires_in: 3600 }
}
// Delega: Frontend che passa il contesto utente al backend
async function delegateToBackend(userToken, backendAudience) {
const response = await fetch(`${AURIS_DOMAIN}/api/auth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: userToken,
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',
audience: backendAudience,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
}),
})
return await response.json()
}
// Utilizzo
const impersonatedToken = await impersonateUser(adminAccessToken, 'user-123')
const delegatedToken = await delegateToBackend(userAccessToken, 'billing-service')Parametri della Richiesta
| Parametro | Obbligatorio | Descrizione |
|---|---|---|
grant_type | Sì | Deve essere urn:ietf:params:oauth:grant-type:token-exchange |
subject_token | Sì | L’access token esistente da scambiare |
subject_token_type | Sì | Deve essere urn:ietf:params:oauth:token-type:access_token |
requested_token_type | No | Di default urn:ietf:params:oauth:token-type:access_token |
requested_subject | No | ID dell’utente target per l’impersonazione. Omettere per la delega. |
audience | No | Audience target per il nuovo token. Usato nella delega. |
scope | No | Scope richiesto per il nuovo token. Non può superare lo scope del token originale. |
client_id | Sì | Il client ID dell’applicazione |
client_secret | Sì | Il client secret dell’applicazione |
Il Claim act
Il token exchange aggiunge sempre un claim act (attore) al token risultante. Questo claim crea una catena verificabile che mostra chi ha effettivamente eseguito lo scambio:
Impersonazione semplice
{
"sub": "user-456",
"act": {
"sub": "admin-123"
}
}Delega a catena
Se un token che già contiene un claim act viene scambiato di nuovo, la catena cresce:
{
"sub": "user-456",
"act": {
"sub": "service-b",
"act": {
"sub": "service-a",
"act": {
"sub": "admin-123"
}
}
}
}Questa catena fornisce una traccia di audit completa di ogni servizio e utente coinvolto nella sequenza di token exchange.
Validare i Token Scambiati
Quando la tua API riceve un token con un claim act, puoi ispezionarlo per capire la catena di delega:
import { verifyToken } from '@auris/js/jwt-verify'
async function handleRequest(req) {
const payload = await verifyToken(req.headers.authorization.slice(7), {
jwksUrl: 'https://auth.tuodominio.com/.well-known/jwks.json',
})
// Controlla se si tratta di un token impersonato o delegato
if (payload.act) {
console.log(`Azione eseguita da ${payload.act.sub} che agisce come ${payload.sub}`)
// Potresti voler registrare o limitare certe operazioni per i token impersonati
if (isDestructiveOperation(req)) {
throw new Error('Le operazioni distruttive non sono consentite tramite token impersonati')
}
}
}Considerazioni sulla Sicurezza
- Applicazione dei permessi: L’impersonazione richiede
impersonate:userse la delega richiededelegate:tokens. Questi sono permessi sensibili che dovrebbero essere concessi con parsimonia. - Audit logging: Ogni token exchange viene registrato con l’attore originale, il soggetto target, il tipo di scambio e il timestamp. Questi log sono visibili nella Console Auris sotto Log.
- Restrizione dello scope: I token scambiati non possono avere uno scope più ampio del token originale. Puoi solo restringere lo scope, mai espanderlo.
- Client confidenziale obbligatorio: Il token exchange richiede l’autenticazione del client. I client pubblici non possono eseguire scambi.
- Durata del token: I token scambiati hanno una durata predefinita più breve (1 ora) e non possono superare la durata residua del token originale.
L’impersonazione è una capacità potente. Assegna il permesso impersonate:users solo a ruoli amministratori fidati. Considera di aggiungere controlli aggiuntivi nel layer applicativo, come bloccare l’impersonazione per operazioni distruttive o richiedere un motivo/numero di ticket.
Endpoint API
/api/auth/tokenEndpoint token. Per il token exchange, imposta grant_type=urn:ietf:params:oauth:grant-type:token-exchange con i parametri descritti sopra. Richiede l’autenticazione del client.
/api/oauth/token-exchangesRequires: view:token_exchangesElenca i recenti eventi di token exchange. Filtrabile per utente, tipo (impersonazione/delega) e intervallo di date.
Permessi Richiesti
| Operazione | Permesso |
|---|---|
| Esegui scambio di impersonazione | impersonate:users |
| Esegui scambio di delega | delegate:tokens |
| Visualizza la cronologia dei token exchange | view:token_exchanges |
| Abilita Token Exchange su un’applicazione | manage:applications |
Guide Correlate
- Client Credentials M2M — Autenticazione server-to-server senza token exchange
- Claim JWT Personalizzati — Aggiungere claim personalizzati agli access token
- Ruoli e Permessi — Gestione dei permessi richiesti per il token exchange