JWT
JWT è uno standard Web per trasmettere dati in un leggero formato testuale. Questi dati possono essere firmati con una Firma Digitale sfruttando lo standard JWS (per ottenere appunto un JWT firmato) oppure crittografati, usando lo standard JWE e ottenere così un JWT crittografato.
In generale, è molto probabile che vi imbattiate in un JWT firmato. Personalmente, non mi è mai capitato (per fortuna) di trovare applicazioni che utilizzino (o società che propongano di utilizzare) un JWT non firmato.
Struttura di un JWT
Un
JWT firmato si compone di tre parti, tutte codificate base64 (secondo le specifiche di
URL encoding). Qualcosa tipo:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Le tre parti sono separate da un punto, eccole:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
La prima parte viene chiamata
header, la seconda
payload e la terza
signature. E serve appunto a garantire l'integrità del
JWT.
Header di un JWT
All'interno dell'
header di un JWT viene specificato l'agoritmo di
crittografia utilizzato per generare l'
hash della
Firma Digitale e il tipo di
JWT.
Decodificando con qualunque base64 decoder, la stringa (l'
header del JWT) di prima, che ricordo era:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Otterremmo:
{
"alg":"HS256",
"typ":"JWT"
}
Che come già detto, sono la
crittografia utilizzata per generare l'
hash della
Firma Digitale e il tipo di
JWT.
Payload di un JWT
Come per l'
header del JWT, prendiamo la stringa del JWT di esempio e concentriamoci sul
payload del JWT:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Decodificandolo dal
base64 otterremmo:
{
"sub":"1234567890",
"name":"John Doe",
"iat":1516239022
}
All'interno del
payload di un JWT vengono inseriti i dati che vogliamo trasmettere (per questo si chiama
payload).
JWT claims
Ogni proprietà del
payload di un JWT viene definito
claim. I claim previsti dallo standard sono chiamati
JWT Registered Claims e sono tutti opzionali (quindi si può scegliere quali usare e quali no). Poi si può scegliere di usare altri claim personalizzati, i
JWT Public Claims e i
JWT Private Claims.
JWT Registered Claims
Claim | Significato | Descrizione |
---|
iss | issuer | L'emittente del JWT |
sub | subject | Il soggetto del JWT. Può essere per esempio l'ID utente che ha effettuato l'accesso |
aud | audience | I destinatari del JWT |
exp | expiration time | La scadenza del token |
nbf | not before | L'inizio di validità del JWT |
iat | issued at | Il momento in cui il JWT viene generato |
jti | jwt id | Identificatore univoco del JWT |
JWT firmato
La differenza tra un
JWT firmato e un
JWT non firmato è la presenza del campo
signature nel JWT. Come abbiamo visto nella
Struttura di un JWT, l'ultimo componente dopo il secondo punto è proprio la firma, che permette di verificare l'integrità del messaggio. Se un JWT non è firmato, nell'header non deve essere ovviamente specificato l'algoritmo di
crittografia utilizzato per generare l'
hash della
Firma Digitale.
JWT e oAuth2
I
JWT firmati sono lo
standard de facto per generare l'
access token richiesto dal framework autorizzativo
oAuth 2. Questo perché il
JWT firmato è autoreferenziale e può essere verificato grazie alla
crittografia asimmetrica e alla
chiave pubblica.
Approfondimenti su oAuth 2 e JWT
Ho preparato alcuni articoli di approfondimenti su oAuth 2 che potete trovare qui:
Sicurezza e JWT
Questo articolo è solo un primo approccio all'argomento
JWT. Per studiarlo al meglio e conoscerne le implicazioni di sicurezza, vi consiglio di acquistare il mio
libro Cyber Security per Applicazioni Web.
Libro Cyber Security per Applicazioni Web
Hai trovato interessante l'articolo "
JWT"? Acquista il libro Cyber Security per Applicazioni Web e accresci le tue competenze sulla Sicurezza Informatica.
Cyber Security per Applicazioni Web è un
libro di Sicurezza Informatica applicativa dedicato a proteggere lo strato di frontend e il layer di integrazione con API REST.