I
meccanismi di autenticazione che agiscono sul protocollo HTTP (esempio: cookies) sono tradizionalmente utilizzati in applicazioni web dove il contenuto, o gran parte della business logic, è gestita dal server.
Il meccanismi necessari a rendere il protocollo HTTP stateful hanno due conseguenze negative:
â— Riducono la scalabilità: il server deve mantenere in memoria le informazioni di sessione per ciascun utente autenticato in un dato momento
â— Aumentano l’accoppiamento tra client e server: La business logic deve essere gestita in larga parte dal server
Nel caso di applicazioni che si appoggiano ad un backend che offre servizi REST API, l’implementazione dell’autenticazione presenta ostacoli aggiuntivi dovuti al fatto che il server in questo caso non “conserverà” alcuna informazione dell’utente perché ogni richiesta è a se stante per definizione (REST = REpresentational “State” Transfer) essendo l’ambiente “Stateless”.
Sono tanti i motivi per preferire architetture REST, come ad esempio la scalabilità (non tenere lo “stato” riduce drasticamente la complessità e le risorse necessarie).
Per evitare, soprattutto per motivi di sicurezza, che l’utente dal client invii ad ogni richiesta le sue credenziali, si possono implementare dei sistemi di autenticazione come il JWT (JSON Web Tokens).
cos’è un JSON?
JavaScript Object Notation (JSON) è un formato di interscambio dati “leggero”, basato su su convenzioni comunemente usate in linguaggi come C++, Javascript, Java, etc.
Perché è così diffuso oggi giorno?
Semplice da leggere per umani e al tempo stesso facile effettuare il parsing in modo automatico.
Basato sul linguaggio Javascript, anche se il tipo di strutture dati che permette di codificare sono comune alla maggior parte dei linguaggi oggi esistenti, permette in particolare di rappresentare:
â— Collezioni di coppie chiave-valore (comunemente
usate per definire dizionari, oggetti, hashmap,etc)
â— Liste ordinate di elementi (comunemente definiti
come array, vettore, liste, etc)
Cos’è un JSON WEB TOKET
Il principio di funzionamento è mostrato in figura.
â— Il token è generato dal server al momento dell’autenticazione
â— Il token contiene non solo un identificativo del client, ma tutte le informazioni che servono alla business logic (ex il ruolo dell’utente)
â— Il token è firmato dal server e non può quindi essere manomesso
Dato che contiene tutte le informazioni associate ad un utente, il server non deve tenere in memoria i dati relativi alla sessione.
Tradeoff: banda vs. utilizzo memoria del server
Il server può “recuperare” la sessione utente senza mantenerla in memoria e senza effettuare query aggiuntive al database.
Diminuisce l’accoppiamento client-server e aumenta la scalabilità
Il token può essere anche scambiato tra domini differenti in contesti di single-sign-on.
â— Un utente può autenticarsi su un determinato dominio A e
ricevere un JWT firmato da A
â— Il JWT può essere inviato al dominio B che può verificare (attraverso la firma digitale) se è stato effettivamente generato da A (di cui si fida)
â— Il dominio B opera considerando l’utente come autenticato perché il processo di autenticazione è già stato gestito da A
I vantaggi di JWT sono diversi come ad esempio il fatto che per natura un JSON è più sintetico di un XML. Inoltre la maggior parte dei linguaggi di programmazione prevedono una deserializzazione dei JSON direttamente in oggetti ma nessun supporto analogo esiste per l’XML. Ultimo aspetto ma non meno importate è la sicurezza in quanto l’SWT ed il SAML possono essere “signati” solo utilizzando una chiave condivisa simmetrica con tutti i rischi che ne conseguono.
In pratica quando l’utente esegue il login, il sistema verificherà le credenziali ed in caso positivo rilascerà un token che il client dell’utente dovrà usare per ogni successiva richiesta sino allo scadere della validità dello stesso
Nel caso delle NOTIFICHE WEB PUSH
I JWT sono utilizzati per
autenticare le richieste al PUSH SERVICE come meccanismi di autenticazione OAuth 2.0, dove il Server della applicazione invia una richiesta di autenticazione al PUSH service, generando un token firmato con la chiave PRIVATA con le informazioni e le invia al server del push service che lo utilizzerà per autenticare la notifica.
Il token di solito è composto da
3 parti che sono la rappresentazione base64url di altrettante sezioni chiamate rispettivamente: Header, Payload e Signature,
unite da un PUNTO
Nell’header viene specificato il tipo di token (JWT) e l’algoritmo usato per cifrare, per le notifiche push l’algoritmo scelto è:
Elliptic curve based JSON Web Signatures (ES256 - EC P-256 DSA with SHA-256) dove la firma viene eseguita con la chiave PRIVATA EC (che fa coppia con la chiave pubblica che abbiamo condiviso con il server al momento della sottoscrizione).
Quindi la prima parte:
header = {
“alg”: “ES256”,
“typ”: “JWT”
}
La seconda parte: Il payload conterrà i “claims” ossia delle proprietà ed altre personalizzate che tipicamente dovrebbero contenere al minimo la username o campo simile per identificare l’utente, nell’autenticazione per le push Notification le proprietà necessarie sono 3:
payload = {
"aud" => https://fcm.googleapis.com, //server endpoint
"exp" => time() + 4 * 3600, // scadenza
"sub" => "mailto: mailservizio@email.com” // una email
}
La terza parte (signature) verrà utilizzata per verificare che il token non è stato in alcun modo manomesso e se è stata usata la chiave privata come secret (quindi impiegando una coppia di chiavi public/private asimmetriche), sarà anche possibile stabilire con certezza che l’utente specificato nel token è esattamente chi dice di essere (assumendo che la chiave privata non venga divulgata e quindi solo la parte del sistema che si occupa di generare il token la conosce).
Ovviamente nel payload non vanno inserite informazioni sensibili dell’utente quali ad esempio la password in quanto chiunque in possesso della chiave pubblica sarà in grado di decodificare il token e leggerne il contenuto.
La signature si ottiene utilizzando l’algoritmo di cifratura a cui vengono passate le prime 2 parti già in base64url con la chiave segreta.
Firma = HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)
il token quindi sara: base64UrlEncode(header)+”.”+base64UrlEncode(payload)+”.”+base64UrlEncode(firma)
il risultato finale sarà della forma:
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY
3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdC
I6MTUxNjIzOTAyMn0.tyh-VfuzIxCyGYDlkBA7DfyjrqmSHu6pQ2hoZu
FqUSLPNY2N0mpHb3nk5K17HWP_3cYHBw7AhHale5wky6-sVA
Sito di riferimento:
jwt.io
Per maggiori informazioni,
Contattaci e non esitare a fare le tue richieste...