Per Iniziare
Comincia dalle basi e scopri come utilizzare Mia-Platform a piccoli passi.
Comincia dalle basi e scopri come utilizzare Mia-Platform a piccoli passi.
Inizia ora
Diventa Partner certificato e scopri tutti i benefici del Partner Program.
Scopri il nostro programma
In questo articolo parleremo di come gestire l’autenticazione machine to machine (M2M) attraverso il protocollo di autorizzazione OAuth 2.0.
Cercheremo di fare luce sulle differenze tra autorizzazione, autenticazione e meccanismo di delega dell’autorizzazione. Faremo riferimento alla specifica OpenID Connect 1.0 (OIDC) dalla quale abbiamo preso spunto per l’implementazione dei metodi di autenticazione.
Nel prossimo articolo illustreremo e descriveremo la nostra implementazione del meccanismo di autenticazione e autorizzazione M2M attraverso il componente Client Credentials. Inoltre, abbiamo scritto anche un articolo riguardo i Service Account.
Prima o poi capita a tutti di dover esporre dati via API verso l’esterno e di doverne consentire il consumo esclusivamente ai client designati.
Entrano qui in gioco parecchi concetti come login, credenziali, token, permessi, autorizzazione, autenticazione, il flusso e l’ordine in cui determinate azioni devono essere effettuate, e così via. Ognuno di questi concetti ha un significato e un confine preciso. Cerchiamo quindi di fare un po’ di chiarezza.
Per prima cosa spieghiamo la differenza fra autenticazione e autorizzazione, due termini spesso utilizzati in maniera intercambiabile, ma che hanno in realtà due significati e funzioni differenti.
L’autenticazione permette di verificare che il chiamante sia chi afferma di essere e quindi di verificarne l’identità. Questa operazione viene fatta tramite la validazione di credenziali che possono essere password, dati biometrici, firme digitali e altre modalità in base al livello di sicurezza richiesto dal sistema. L’autenticazione è solitamente eseguita prima dell’autorizzazione.
Una volta che l’utente è autenticato, l’autorizzazione stabilisce le risorse a cui esso può accedere tramite l’assegnazione di permessi agli utenti, regole e policy.
Riassumendo, si può dire che l’autenticazione permette di verificare l’identità del chiamante, mentre l’autorizzazione consente di determinare le risorse a cui il chiamante può o non può accedere.
Non è semplice gestire autorizzazione e autenticazione. Soprattutto nel caso in cui il server che vuole accedere a una risorsa di un terzo è un server diverso da quello che la possiede.
Fortunatamente esistono dei protocolli che aiutano a scegliere e implementare il corretto flusso per il proprio caso d’uso. Il più noto è il protocollo OAuth 2.0 di cui parleremo di seguito. Scopriremo che OAuth 2.0 non è una specifica esaustiva sui meccanismi di autenticazione e autorizzazione, ma si occupa di descrivere molteplici meccanismi per l’ottenimento di un token autorizzativo.
OAuth 2.0 (OAuth) è descritto nella specifica RFC 6749 titolata “The OAuth 2.0 Authorization Framework”. Sul sito oauth.net è introdotto come “OAuth 2.0 is the industry-standard protocol for authorization”. Da questi contenuti si è portati a pensare che tale protocollo si occupi di autorizzazione in senso stretto. Eppure OAuth sottintende che il sistema che applica le policy autorizzative e che concede l’accesso alle risorse, sia già esistente.
Ma allora di che cosa si occupa OAuth 2.0?
Questo protocollo può essere meglio inquadrato se descritto come un protocollo di delega degli accessi. Il ruolo che OAuth si pone è quello di descrivere come un client possa accedere alle risorse protette (Resource) di un utente (Resource Owner), le quali risiedono su un server terzo (Resource Server), senza che il client venga a conoscenza delle credenziali del Resource Owner.
Figura 1: Flusso astratto del protocollo
Questo avviene, come descritto dal flusso teorico del protocollo visibile in figura 1, tramite i seguenti passaggi:
Prima di fornire ulteriori spiegazioni è necessario fare un paio di precisazioni.
Come un occhio attento avrà già notato dalle prima righe di questo paragrafo, OAuth non si occupa di autenticazione, al più ne dà qualche suggerimento.
OAuth non è neppure una guida esaustiva su come implementare i meccanismi di autorizzazione all’interno del proprio sistema; bensì è una specifica che descrive la sequenza di azioni che devono (MUST) essere fatte, quelle che dovrebbero (SHOULD) essere fatte, quelle che possono essere fatte (MAY) e quelle che non devono essere fatte (MUST NOT). Il modo in cui queste azioni possono essere implementate va oltre le scopo di questo protocollo, nonostante questi spesso fornisca alcuni suggerimenti a riguardo.
Per esempio, al punto 3.1 Authorization Endpoint della specifica, viene detto:
“The authorization endpoint is used to interact with the resource owner and obtain an authorization grant. The authorization server MUST first verify the identity of the resource owner. The way in which the authorization server authenticates the resource owner (e.g., username and password login, session cookies) is beyond the scope of this specification.”
La specifica quindi impone che per usare l’endpoint di autorizzazione, l’Authorization Server debba verificare l’identità – autenticare – del Resource Owner, ma non ne descrive le modalità.
Questo è solo un esempio dei molteplici punti in cui la specifica OAuth 2.0 lascia libertà di implementazione. Questa libertà non è spesso apprezzata dagli sviluppatori, i quali si trovano a non sapere come implementare gli aspetti che la specifica non definisce. Il rischio è inoltre quello di effettuare un’implementazione che non rispetta determinati requisiti di sicurezza.
Anche per questo motivo ci si affida spesso a servizi esterni (Okta, Auth0, Authlete) che implementano i protocolli sopra citati rispettando al contempo i necessari requisiti di sicurezza e offrendo molteplici alternative di implementazione, come ad esempio diverse modalità di autenticazione.
Quindi lo scopo principale della specifica OAuth 2.0 è definire:
La parte più interessante di questo protocollo è proprio il flusso di ottenimento del token. Vediamo come può avvenire.
Il protocollo OAuth 2.0 descrive quattro possibili flussi autorizzativi e ognuno di essi ha un particolare caso d’uso.
La spiegazione nel dettaglio di ciascuno di questi flussi va oltre gli scopi di questo articolo; in rete sono presenti molteplici risorse che spiegano nel dettaglio i flussi sopra citati (1, 2, 3).
Ci concentreremo esclusivamente sull’ultimo flusso autorizzativo, il Client Credentials Grant.
Client Credentials Grant è sicuramente il più semplice dei flussi autorizzativi di OAuth 2.0. Lo si può intuire dalla seguente rappresentazione grafica:
Figura 2: Flusso del Client Credential Grant
Come emerge dalla figura 2, questo flusso non prevede l’interazione con un utente, né con un dispositivo dell’utente: il client è un server – quindi una macchina – e deve accedere a una risorsa su un Resource Server, un’altra macchina. Si tratta esattamente dell’ipotesi che abbiamo illustrato all’inizio dell’articolo: il consumo di una API attraverso un’interazione M2M.
La specifica OAuth 2.0 (4.4 Client Credentials Grant) afferma:
“The client can request an access token using only its client credentials (or other supported means of authentication) when the client is requesting access to the protected resources under its control, or those of another resource owner that have been previously arranged with the authorization server (the method of which is beyond the scope of this specification).
The client credentials grant type MUST only be used by confidential clients.”
Come abbiamo già visto, OAuth non si occupa di autenticazione e la specifica semplicemente afferma che per l’ottenimento dell’Access Token sono sufficienti le credenziali del client o altri mezzi di autenticazione supportati.
Questo metodo è utilizzato quando il client richiede accesso a risorse protette:
La RFC spiega infine il formato di input e output della richiesta dell’Access Token.
Può sembrare a questo punto che il flusso Client Credential sia così banale da risultare inutile implementarlo, cadendo nella tentazione di implementare un proprio meccanismo senza quindi dover aderire a queste specifiche. La sua forza risiede proprio nella sua semplicità. OAuth 2.0 standardizza il flusso autorizzativo con cui si può usufruire di una API in un’interazione M2M.
In un dialogo M2M Mia-Platform – grazie a un microservizio appositamente sviluppato – offre la possibilità di accedere alle proprie API attraverso il meccanismo standard Client Credentials di OAuth 2.0 rendendo l’integrazione il più semplice e veloce possibile.
OpenID Connect 1.0 è un meccanismo costruito al di sopra di OAuth 2.0 che standardizza l’identificazione dell’utente. Nasce dall’esigenza di ridurre lo sforzo impiegato nell’integrarsi con Identity Provider per autenticare un utente e ottenere informazioni addizionali su di esso.
In passato ogni Identity Provider costruiva su OAuth 2.0 dei permessi e delle API custom dediti all’ottenimento di informazioni di identificazione su un utente. Di conseguenza, un client per mettere a disposizione degli utenti svariati provider di autenticazione/identificazione – i classici login con Google, Facebook, LinkedIn, etc – doveva implementare per ognuno di essi meccanismi differenti.
OIDC 1.0 standardizza questi meccanismi mettendo a disposizione strumenti come l’ID Token, l’API di /userinfo e nomi standard per varie proprietà di identificazione (nome è given_name, cognome è family_name, nome completo è name, …) riducendo drasticamente i tempi di integrazione con Identity Provider.
Tutto ciò ha enorme valore laddove sia presente un utente, ma l’interazione descritta in questo articolo è tra due macchine. Perché parlarne allora?
Come detto in precedenza, OAuth 2.0 rimane abbastanza vago sulle modalità tramite cui il client può autenticarsi con l’Authentication Server.
Nel paragrafo 2.3 Client Authentication del RFC 6749 viene infatti affermato “The authorization server MAY accept any form of client authentication meeting its security requirements”, lasciando libertà di implementazione per la Client Authentication.
OIDC non solo standardizza l’identificazione dell’utente, ma definisce alcune modalità semplici e sicure per effettuare la Client Authentication.
La registrazione dei client e il flusso Client Credentials di OAuth 2.0, e i metodi di Client Authentication client_secret_basic e private_key_jwt descritti in OpenID Connect 1.0 sono stati implementati in Mia-Platform all’interno del componente Client Credentials.
Nel prossimo articolo descriveremo come queste specifiche sono stato implementate, mostrando quindi come un client esterno può accedere a una API erogata da Mia-Platform oppure da un servizio terzo, usando Mia-Platform come provider di autenticazione e autorizzazione.
Articolo scritto da Davide Tantillo, Senior Technical Leader, e Davide Bianchi, Senior Technical Leader.