Authentication vs Authorization

Ancora una volta mi trovo in mezzo ad una diatriba; se vogliamo un dilemma semantico, o semplicemente due concetti che vengono erroneamente usati in maniera interscambiabile nel comune linguaggio tecnico.

Mi sto riferendo alle due parole Authentication e Authorization che da molti anni calcano la scena IT per dei sistemi più o meno complessi, web e desktop.

La sicurezza in questi ultimi tempi - come mai in passato - ha assunto un ruolo non solo importante, ma fondamentale per ogni architettura che si rispetti; tanto, che non solo è basilare creare e nutrire il dato, ma preservarlo incontaminato, sicuro, protetto proporzionalmente al suo valore.

E' così che, ogni due/tre anni nascono nuovi tecniche per difendere l'informazione, che vanno a braccetto con altrettante tecniche di "hacking" - perdonatemi il termine non propriamente preciso - per forzare o addirittura distruggere le informazioni stesse.

Ma oggi non sono qui a parlare relativamente a specifiche di sicurezza informatica - ci sono colleghi di rara bravura che potrebbero facilmente eclissarmi con "la lingua legata dietro alla schiena" - ma per condividere un mio personale pensiero sull'argomento.

Partiamo con il dire che "autenticazione" ed "autorizzazione" sono due termini ben distinti, ortogonali, che rappresentano due aspetti egualmente importanti del processo di security di una piattaforma applicativa. In breve:
  • Authentication - Rappresenta in qualche modo "core" del processo di protezione di un dato. E' il meccanismo che permette di identificare un particolare utente del sistema, sulla base di una o più credenziali di accesso fornite al momento del primo contatto con la piattaforma (più precisamente quando si accedere ad una funzione o dato protetto). Esso risponde alla semplice domanda: "E' possibile identificare univocamente l'operatore che sta davanti al computer? E, se si, a quale utente registrato corrisponde?".
  • Authorization - E' il processo di assegnazione di un permesso di esecuzione - ad un utente accreditato - necessario per portare a termine una certa azione nel contesto della piattaforma applicativa in questione. La domanda in questo caso è altrettanto banale: "Che cosa può fare, nel contesto applicativo, l'utente XYZ che ho riconosciuto durante il processo di autenticazione, sui dati e sulle strutture del sistema?"
Come detto i due concetti sono nettamente separati nel loro significato; ma è evidente che il processo di autorizzazione non può in nessun modo prescindere da quello di autenticazione; come potrei altrimenti assegnare un diritto a qualcuno di cui non conosco l'identità?

L'identificazione, solitamente, si svolge attraverso l'uso delle tre classiche metodologie ampiamente descritte in letteratura, e si basa sempre su un input proveniente dall'operatore stesso che chiede di essere riconosciuto:
  • Un input sulla base di qualche cosa che l'utente sa; per esempio la classica username e password, un codice PIN, o qualche cosa di più "esotico".
  • Un input sulla base di qualche cosa che l'utente ha; per esempio un token, una smartcard, oppure una chiave hardware di qualche genere.
  • Un input sulla base di qualche cosa che l'utente è; per esempio utilizzando dei sensori biometrici come un lettore di impronte digitali o - se vogliamo fare una figata - un sistema di scansione retinea. E magari fermiamoci qui perchè rischiamo di cadere nella fantascienza...
Il motivo per cui questo due termini sono sempre finiti nello stesso calderone, è dovuto al fatto che insieme rappresentano il "core" del layer di security di un sistema informativo. E, spesso e volentieri, sono sempre stati architetturalmente "annegati" nel sistema stesso che ne andava a beneficiare.

Riagganciandomi al mio precedente post, mi sembra doveroso segnalare come, sempre di più, si senta la necessità di disaccoppiare il layer di sicurezza - in architetture service-oriented - dal resto dell'applicazione; questo in concomitanza con il proliferare di sistemi ed applicazioni, ciascuno dei quali avrebbe una propria banca dati utenti, eterogenea e difficilmente manutenibile. Inoltre, dal punto di vista della persona fisica, l'operatore, il numero di username/password che si è costretti a ricordare diventa sempre maggiore con generale disagio e difficoltà di utilizzo.

Pensate al trattamento che i grandi competitor come Google, Microsoft (per citare solo quelli che conosco meglio) riservano allo strato identificativo, cioè l'autenticazione. Una identità "Google" è centralizzata, è fornita come servizio a se stante, e sempre (sempre) è isolata dal sistema sulla quale sarà fruita. In parole povere il concetto è questo: "Utente, forniscimi le tue credenziali di accesso Google, ed io - servizio di autenticazione - provvedo al tuo riconoscimento e preparo il terreno per le altre applicazioni presenti nel mio ecosistema che vorrai utilizzare". In pratica i sistemi federati si dovranno "fidare" di una entità superpartes (il servizio di "Auth") per evitare di implementare i meccanismi di "identity" all'interno di ciascun differente applicativo.

Ma attenzione: qui stiamo parlando di identificazione, quindi dell'autenticazione di un particolare utente; non siamo minimamente accennando al processo di autorizzazione all'uso di una particolare risorsa o funzionalità.

Scorporare e, di fatto, centralizzare il processo di autorizzazione sarebbe non poco dispendioso, e necessiterebbe di un livello di astrazione non sempre semplice da raggiungere. Pensate di dover generalizzare i permessi di lettura, scrittura ed eliminazione da una anagrafica di prodotti per il software ABC, centralizzando il tutto sul server di autorizzazione; sopratutto considerando che quest'ultimo è assolutamente agnostico al processo funzionale svolto dal sistema esterno. Si rischierebbe facilmente di portare della logica di business di ABC all'interno del sistema di "identity": e non è certo quello lo scopo che vogliamo raggiungere.

Personalmente - e chiaramente si può essere d'accordo o meno con questa affermazione - penso che l'autenticazione vada trattata a livello globale, centralizzata ed accessibile dal sistema di "Auth" attraverso dei servizi web (ove possibile, chiaramente). Ma l'autorizzazione è bene che venga implementata all'interno dell'applicazione stessa che farà uso dei permessi assegnati all'utente in questione; certo, fidandosi di "Auth" per quanto riguarda il riconoscimento dell'operatore in questione, ma preservando all'interno del proprio database (per farla semplice) il concetto di "profilo utente". Quest'ultimo accoppierà l'identità digitale con le grant assegnate secondo una logica funzionale ben definita e nota nel contesto d'uso.

Ultimo "tip", prima di chiudere. Da qualche mese mi sto divertendo (per così dire) con il protocollo "OAuth2" e le sue incarnazioni .NET. Il framework OWIN (Open Web Interface for .NET) mi sembra estremamente versatile da questo punto di vista; permette di interfacciare provider esterni con estrema semplicità (Google, Twitter, Facebook, ecc), realizzare le basi per i propri server di autenticazione, lavorare con chimate CORS (Cross-Origin Resource Sharing), e approcciare un processo identificativo basato su token (Bearer, JWT) che viaggiano nell'header delle request.

L'integrazione con framework client-side (AngularJs, di cui sono un grandissimo fan) è tutto sommato abbordabile, e permette di realizzare sistemi moderni, flessibili e manutenibili nel corso del tempo; l'integrazione in piattaforme mobile è anch'essa gestibile senza un numero eccessivo di imprecazioni "developer-side".

Ma la chiave resta sempre il disaccoppiamento. E ancora una volta mi domando: "Per quale motivo, in ogni singola applicazione che realizzo, devo incorporare (per copia o riferimento, of course) un framework di gestione degli utenti, quando posso delegare questa noiosa e delicata parte ad un sistema esterno la cui unica responsabilità è certificarmi l'identità di un operatore?".

La risposta è che non ho motivo di farlo. O meglio...non mi viene in mente nessun motivo "sano"...

Commenti

Post popolari in questo blog

Cancellazione fisica vs cancellazione logica dei dati

Restore di un database SQL Server in un container Docker

Costruire una DataSession custom con Chakra.Core