identityServer4

in Architetture Software

IdentityServer4 – AspCore Identity

Reading Time: 5 minutes

Prima di procedere con l’implementazione di un’applicazione AspNet Core con un sistema di autenticazione/autorizzazione integrato, è necessario introdurre IdentityServer4.

Partendo dalla documentazione ufficiale Microsoft, Identity viene definito come : ” ASP.NET Core Identity is a membership system that adds login functionality to ASP.NET Core apps. Users can create an account with the login information stored in Identity or they can use an external login provider.” and “Identity can be configured using a SQL Server database to store user names, passwords, and profile data.

Dalla definizione si capisce come l’interazione tra client e Identiy Server consenta di creare utenti locali (memorizzati all’interno di SQL Server) o su servizi di terze parti, come Google, Facebook e Microsoft. Identity definisce una serie di standard relativamente alla scrittura dei dati degli utenti (tabelle, relazioni tra tabelle, ecc…) e i metodi da utilizzare per gestire ed interagire con i profili degli utenti. Ad esempio, per modificare una password di un utente è presente un metodo che consente di memorizzarla in formato hash all’interno della relativa tabella. Identity mette a disposizione tutta una serie di metodi con cui è possibile interagire con gli utenti.

Identity, ovviamente, non copre tutti gli scenari possibili in termini di metodi e dati presenti all’interno del profilo degli utenti: il team di sviluppo di Microsoft non potrebbe gestire tutte tutti i casi possibili. Identity, quindi è facilmente estendibile, ad esempio aggiungendo campi personalizzati al profilo degli utenti, e funzioni aggiuntive per l’interazione con i dati utente.

Quando utilizzare Identity?

IdentityServer4 non si occupa di gestire gli utenti: gestisce la generazione di token, gli endpoint, i protocolli OAuth2 e OIDC, gli accessi di applicazioni client. Per poter utilizzare IdentityServer4 dobbiamo fornirgli degli utenti.

Attenzione! Non è necessario utilizzare Identity con IdentityServer4. E’ anche possibile utilizzarli separatamente.

Si può utilizzare Identity per autenticare una singola applicazione, ma si perde la possibilità di creare un Identity Provider, che consenta di centralizzare l’accesso a tutte le applicazioni che ne faranno richiesta. In pratica la creazione di un sistema SSO (single sign on).

Le applicazioni moderne non possono basare il loro modello di sicurezza solo attraverso username e password. Per poter rendere robusto e sicuro il processo di autenticazione per APP/API è necessario introdurre layer di sicurezza scalabili e resistenti a cyber-attacchi.

Uno di questi framework è proprio IdentityServer4.

IdentityServer4:

  • è la nuova versione di IdentityServer
  • è un framework opensource che include OAuth e OpenId Connect
  • fa parte del progetto .NET Foundation

Quando vogliamo implementare lo standard OpenId, è necessario procedere con l’implementazione di tutti gli aspetti del protocollo: l’implementazione richiede un effort per lo sviluppo molto alto. Poichè OpenId si basa su uno standard ben definito, sarebbe molto comodo poter utilizzare un componente che ne implementa tutte le caratteristiche, senza doverle riscrivere. Questo componente è proprio IdentityServer4.

IdentityServer4 fornisce inoltre tutto il necessario per l’implementazione di un sistema di generazione token, implementando un servizio di autenticazione completo utilizzabile da client differenti (web, api, servizi di terze parte, ecc…).

Utilizzando IdentityServer4, lo sviluppatore dovrà sviluppare il codice relativo alle procedure di login, logout: tutto il resto, in ottemperanza allo standard del protocollo, sarà già implementato all’interno di IdentityServer4.

Funzionalità

IdentityServer4 offre le seguenti funzionalità:

  • Autenticazione as service: l’autetenticazione viene implementata come un servizio accessibile da tutte le applicazioni/client in un unico ambiente centralizzato
  • Contiene tutte le funzioni per proteggere risorse di natura differente
  • E’ un provider di identità open-source
  • E’ un nodo Single-Sign-On che consente l’autenticazione di utenti e/o app
  • Può essere utilizzato per proteggere risorse web ma anche web api
  • Consente di emettere token di identità e di accesso ai dati
  • Consente di validare token
  • Rappresenta un gateway di accesso verso sistemi di terze parti (come Facebook, Google, Microsoft, ecc…)

Esempio di flusso

L’immagine sottostante mostra un esempio di flusso che coinvolge IdentityServer4:

Partendo da sinistra, gli utenti interagiscono con i clients per interfacciarsi direttamente con IdentityServer4 . Il client è una parte di codice che si interfaccia direttamente con IdentityServer4: il client richiede il token di autenticazione (Identity Token) per effettuare l’autenticazione dell’utente, e successivamente il token di accesso (Access Token) per ottenere l’accesso alle risorse.

I token che rientrano nel flusso sono quindi:

  • Identity Token: contiene le informazioni dell’utente, ed è utilizzato per autenticare l’utente
  • Access Token: contiene le informazioni del client e dell’utente, e viene utilizzato per l’accesso alle risorse (es. web, webapi).

Tutto il meccanismo di emissione token è delegato a IdentityServer4, che svolge il suo lavoro in totale autonomia e, nella maggior parte di casi, senza la necessità di modifiche da parte degli sviluppatori.

Tutorial

Il team di sviluppo di IdentityServer4 mette a disposizione una serie di template che possono essere integrati in quelli già presenti all’interno della CLI di dotnet core 3.0. In particolare, quello che verrà utilizzato in questa demo può essere installato dalla linea di comando con:

dotnet new --install "IdentityServer4.Templates"

A questo punto, con nell’elenco dei template utilizzabili e visualizzati con il comando dotnet new troveremo anche:

is4empty : un progetto che utilizza IdentityServer4 vuoto
is4ui: un progetto IdentityServer4 con una semplice UI 

Procediamo con la creazione di un semplice progetto di tipo IdentityServer4:

dotnet new is4empty -n IdentityServer
dotnet new is4ui -n IdentityServer
cd ..
dotnet new sln -n Quickstart
dotnet sln add .\src\IdentityServer\IdentityServer.csproj

i primi due comandi consentono la creaazione di un progetto chiamato IdentityServer empty (viene creata solo la struttura) e successivamente viene aggiunto un progetto contenene la UI di default. Le ultime due righe consentono di aggiungere il nostro progetto ad una soluzione, per poterlo aprire agevolmente utilizzando Visual Studio. A questo punto, effettuando il run all’interno di Visual Studio, verrano scaricate tutte le dipendenze ed il progetto verrà eseguito, mettendo l’istanza di IdentityServer4 in esecuzione sulla porta 5000.

Analizzando il contenuto della cartella Quickstart, troviamo la struttura classica di un’applicazione ASPNET Core MVC, con la classica alberatura Views, Controllers e Model. Inoltre è presente la cartella wwwroot utilizzata per i contenuti statici della nostra applicazione. In particolare il controller AccountController definito all’interno di AccountController.cs contiene la logica per effettuare il login/logout degli utenti. Allo stesso modo, il controller ExternalController definito all’interno ExternalController.cs contiene la stessa logica applicata però all’autenticazione con componenti di terze parti (es. Google, Microsoft, Facebook, ecc…).

Alla prima esecuzione della solution viene generato la chiave tempkey.rsa che IdentityServer utilizza per firmare il token JWT utilizzati in Outh2 e OpenId Connect. Per le applicazioni in produzione, questa chiave dovrà essere generata con un meccanismo differtente. Per le applicazioni in ambiente dev questa chiave è più che sufficiente.

Impostazione delle risorse

Per impostazione di default, IdentityServer4 definisce la sua configurazione tramite un archivio mantenuto in memoria. Questo archivio contiene informazioni per:

  • archivio client
  • archivio di risorse API
  • archivio identità
  • archivio criteri CORS
  • archivio permessi permanenti per token

L’approccio di utilizzare risorse in memory consente di implementare velocemente un ambiente per i test, senza dover utilizzare server sql (sql-lite, sql-server ecc…). Ovviamente questo approccio non può essere riportato in ambiente di produzione, in particolare perchè ogni modifica necessiterebbe il riavvio dell’applicazione: le risorse vengono, infatti, caricate, in fase di startup. Inoltre, se l’applicazione viene riavviata e non è stato predisposto un meccanismo di persistenza dei dati, verrebbero persi i dati raccolti a runtime. Una soluzione piuttosto ovvia è quella di agganciare un meccasismo di persistenza basato su Entity Framework.

Endpoint

Per ottenere l’elenco completo degli endpoint disponibili è possibile accedere al link:

 http: // localhost: 5000 / .well-known / openid-configuration

che visualizzerà tutti gli endpoint creati automaticamente da IdentityServer4. Questo endpoint è molto utile quando è necessario interagire con altri sviluppatori: fornendo i dettagli del risultato della chiamata all’endpoint è possibile estrarre informazioni importanti per lo sviluppo dei client.

Per poter testare il funzionamento di IdentityServer4 è possibile effettuare la login tramite l’utente alice con password alice. Il template dotnet core utilizzato ha infatti generato alcuni utenti direttamente in memory. L’elenco degli utenti creati è visibile all’interno del file TestUsers.cs, presente nella root della solution. TestUsers viene iniettato tramite DI all’interno di AccountController ed utilizzato per autenticare utenti di test.

Nei prossimi post analizzeremo l’integrazione con Identity.