Skip to Content

Token Exchange (RFC 8693)

Il Problema: Un Token Non Va Bene per Tutto

In un’applicazione monolitica, un singolo token di accesso è sufficiente. Ma le architetture moderne non sono monolitiche. Una tipica richiesta può attraversare più servizi:

Utente → Frontend → API Gateway → Order Service → Payment Service → Notification Service

Ogni servizio in questa catena ha diversi livelli di trust, diversi scope e diversi audience. Usare lo stesso token ovunque crea problemi:

ProblemaDescrizione
Token con troppi privilegiIl token del frontend ha read:users write:orders manage:payments ma il Payment Service ha solo bisogno di process:payments. Se il Payment Service viene compromesso, l’attaccante ha accesso a tutti gli scope.
Audience sbagliatoUn token emesso per frontend-app non dovrebbe essere accettato da payment-service.
ImpersonazioneUn admin deve eseguire il debug dell’account di un utente agendo come quell’utente. Non c’è modo standard di “diventare” un altro utente senza conoscere le sue credenziali.
DelegaIl Servizio A deve chiamare il Servizio B per conto dell’utente, ma il Servizio B ha bisogno di conoscere sia l’utente originale che l’identità del servizio chiamante.

Come Funziona il Token Exchange

La Richiesta di Token Exchange

Una richiesta di token exchange è un POST al token endpoint standard con grant_type=urn:ietf:params:oauth:grant-type:token-exchange:

POST /api/auth/token HTTP/1.1 Host: auth.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:token-exchange &subject_token=eyJhbGciOiJSUzI1NiJ9... &subject_token_type=urn:ietf:params:oauth:token-type:access_token &requested_token_type=urn:ietf:params:oauth:token-type:access_token &audience=payment-service &scope=process:payments &actor_token=eyJhbGciOiJSUzI1NiJ9... &actor_token_type=urn:ietf:params:oauth:token-type:access_token

Parametri della Richiesta

ParametroObbligatorioDescrizione
grant_typeSìSempre urn:ietf:params:oauth:grant-type:token-exchange
subject_tokenSìIl token da scambiare — rappresenta l’identità della parte per conto della quale viene fatta la richiesta
subject_token_typeSìIl tipo del subject token
requested_token_typeOpzionaleIl tipo desiderato per il token di output. Default: access_token.
audienceOpzionaleIl servizio o API di destinazione che consumerà il nuovo token
scopeOpzionaleGli scope richiesti per il nuovo token. Deve essere un sottoinsieme degli scope del subject token.
actor_tokenOpzionaleIl token della parte che esegue lo scambio (l‘“attore”)

Impersonazione vs Delega

Impersonazione

Nell’impersonazione, il claim sub del token scambiato è impostato sull’utente target. Il servizio downstream vede le richieste “da” l’utente impersonato. L’attore originale è registrato nel claim act per scopi di audit.

{ "sub": "user-123", "iss": "https://auth.example.com", "aud": "frontend-app", "exp": 1739882700, "act": { "sub": "admin-456" } }

Caso d’uso: Un admin deve riprodurre un bug che riguarda solo l’account di un utente specifico.

Delega

Nella delega, il claim sub del token scambiato rimane l’utente originale. L’attore è registrato nel claim act, ma il token rappresenta ancora la richiesta dell’utente originale, ora mediata da un servizio.

{ "sub": "user-123", "iss": "https://auth.example.com", "aud": "payment-service", "exp": 1739882700, "scope": "process:payments", "act": { "sub": "order-service" } }

Caso d’uso: Chiamate servizio-a-servizio in un’architettura a microservizi.

Differenze Chiave

DimensioneImpersonazioneDelega
sub nel nuovo tokenUtente targetUtente originale (invariato)
Claim actAdmin/attore originaleServizio intermediario
Il downstream vede”Richiesta da utente target""Richiesta da utente originale tramite servizio”
Permesso richiestoimpersonate:usersdelegate:tokens
Livello di rischioAlto (assunzione completa dell’identità)Medio (lo scope può essere ridotto)

L’impersonazione è un’operazione privilegiata. In Auris, solo i client con il permesso impersonate:users possono eseguire scambi di token per impersonazione. Questo permesso non dovrebbe mai essere concesso ai client rivolti agli utenti finali.

Il Claim act: Catene di Delega

Il claim act (attore) è un oggetto JSON incorporato nel JWT che registra chi ha eseguito il token exchange. I claim di attore possono essere annidati per rappresentare una catena di deleghe:

{ "sub": "user-123", "iss": "https://auth.example.com", "aud": "notification-service", "act": { "sub": "payment-service", "act": { "sub": "order-service", "act": { "sub": "api-gateway" } } } }

Questo token racconta una storia: user-123 ha fatto una richiesta tramite api-gateway, che ha delegato a order-service, che ha delegato a payment-service, che ora chiama notification-service.

Auris limita la profondità della catena di delega a 5 per default.

Proprietà di Sicurezza

Riduzione Scope (Mai Espansione)

Il token scambiato non può mai avere più permessi dell’originale. Se il subject token ha scope read:users write:orders, il token scambiato può richiedere read:users (sottoinsieme) ma non read:users delete:users (sovrainsieme).

Trail di Audit

Ogni token exchange è registrato con l’identità del subject token, l’identità dell’actor token, audience e scope richiesti, tipo di scambio, indirizzo IP e timestamp.

Riduzione del Lifetime del Token

I token scambiati hanno sempre un lifetime più breve del token originale. Il default è il 50% del lifetime rimanente del subject token.

Dettagli di Configurazione

Token Exchange è abilitato per applicazione nella Console Auris sotto Applicazioni > (seleziona applicazione) > Impostazioni:

ImpostazioneDefaultDescrizione
Abilita Token ExchangefalseToggle principale
Consenti impersonazionefalseSe questa applicazione può eseguire scambi di impersonazione
Consenti delegafalseSe questa applicazione può eseguire scambi di delega
Profondità massima catena5Profondità massima di annidamento dei claim act
Lifetime token scambiato50%Lifetime del token scambiato come percentuale del lifetime rimanente del subject token

Esempio di Codice: Catena di Delega tra Microservizi

// api-gateway riceve il token dell'utente e deve chiamare order-service async function callOrderService(userAccessToken: string) { const exchangeResponse = await fetch('https://auth.example.com/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: userAccessToken, subject_token_type: 'urn:ietf:params:oauth:token-type:access_token', audience: 'order-service', scope: 'read:orders write:orders', }), }) const { access_token: orderServiceToken } = await exchangeResponse.json() return fetch('https://order-service.internal/api/orders', { headers: { Authorization: `Bearer ${orderServiceToken}` }, }) }

Ogni token exchange — sia impersonazione che delega — crea una voce nel log di audit di Auris. Gli amministratori possono filtrare i log per tipo di scambio per rivedere tutta l’attività di impersonazione. In ambienti ad alta sicurezza, gli eventi di impersonazione possono innescare notifiche in tempo reale al team di sicurezza.

Concetti Correlati