Nel corrente panorama tecnologico la maggior parte delle applicazioni, siano esse mobile, web o desktop, si affidano ad un servizio di back-end costruito sopra una base di dati che racchiude un tutta la logica di funzionamento. Tra i vari aspetti che bisogna considerare per l’implementazione di un solido back-end, uno importante è la gestione dell’autenticazione degli utenti al sistema.

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).

Il principio di funzionamento è mostrato in figura:

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. Esempio di token:

Il token in questo caso sarà composto da 3 parti che sono la rappresentazione base64url di altrettante sezioni chiamate rispettivamente: Header, Payload e Signature.

Nell’header viene specificato il tipo di token (JWT) e l’algoritmo usato per cifrare:

{

  “alg”: “HS256”,

  “typ”: “JWT”

}

Il payload conterrà i “claims” ossia delle proprietà quali ad esempio “iss” (issuer), “exp” (expiration time), “sub” (subject), ed altre personalizzate che tipicamente dovrebbero contenere al minimo la username o campo simile per identificare l’utente.

La signature si ottiene utilizzando l’algoritmo di cifratura a cui vengono passate le prime 2 parti già in base64url ed una chiave segreta. Esempio:

HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

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.

Esistono metodi di generazione del token alternativi come il SWT (Simple Web Tokens) e il SAML (Security Assertion Markup Language Tokens). Tuttavia 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.

Di seguito, la differenza tra un token JWT(JSON) e uno basato su SAML(XML):

Fonte: https://jwt.io