Negli ultimi script abbiamo visto come sia tutto sommato piuttosto immediato supportare bearer token in ASP.NET Web API: una serie di middleware OWIN si occupa della generazione e della validazione, facendo sì che, a valle di questo processo, il principal della richiesta sia popolato con i dati estrapolati dal token.
Ciò fa sì che, in fin dei conti, come sviluppatori ci basti aggiungere l'attributo Authorize ai controller o alle action che vogliamo proteggere, e tutto funziona out-of-the-box, senza che dobbiamo preoccuparci dei dettagli relativi alla validazione dei token stessi.
Questo ragionamento rimane valido anche nel caso di autorizzazione basata sui ruoli. Tutto ciò che dobbiamo fare è attivare il supporto per i ruoli in ASP.NET Identity, come descritto in questo precedente script: https://www.aspitalia.com/script/1194/Usare-RoleManager-Gestire-Ruoli-ASP.NET-Identity.aspx.
Se abbiamo fatto tutto correttamente, non dobbiamo apportare alcuna modifica al nostro codice di ASP.NET Web API. Il metodo GrantResourceOwnerCredentials del token provider (ApplicationOAuthProvider nel template di default) recuperà l'utente, con la sua membership ai vari gruppi esistenti, e popolerà automaticamente i claim di tipo Role all'interno della classe ClaimsIdentity:
public override async Task GrantResourceOwnerCredentials( OAuthGrantResourceOwnerCredentialsContext context) { // .. altro codice qui .. // questo metodo popolerà anche i Claim di tipo Role ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); // .. altro codice qui .. }
Questi claim verranno allegati al bearer token restituito, così che possano essere validati alla successiva richiesta. L'aspetto interessante è che il tutto avviene senza nessuna ulteriore configurazione o logica personalizzata: un ruolo, infatti, non è altro che un tipo particolare di claim. Come tutti i claim, è memorizzato in maniera sicura all'interno del token, che viene poi deserializzato in fase di validazione per popolare il ClaimsPrincipal della richiesta corrente.
Una volta che il ClaimsPrincipal è stato associato alla richiesta corrente, possiamo sfruttarlo per autorizzare una chiamata a un controller in base al ruolo con l'attributo Authorize:
[Authorize(Roles = "Administrators")] public class ValuesController : ApiController { // .. codice qui .. }
Se vogliamo provare che il tutto funzioni, possiamo per esempio impostare artificiosamente la membership del nostro utente di test prima della validazione delle credenziali nel ApplicationOAuthProvide:
public override async Task GrantResourceOwnerCredentials( OAuthGrantResourceOwnerCredentialsContext context) { // Impostiamo in maniera artificiosa la membership al ruolo Administrators await this.EnsureAdministratorAsync(context); // .. altro codice qui .. // questo metodo popolerà anche i Claim di tipo Role ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); // .. altro codice qui .. } private async Task EnsureAdministratorAsync( OAuthGrantResourceOwnerCredentialsContext context) { var roleManager = context.OwinContext.Get<ApplicationRoleManager>(); var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); var group = await roleManager.FindByNameAsync("Administrators"); if (group == null) { await roleManager.CreateAsync(new IdentityRole("Administrators")); var user = await userManager.FindByNameAsync("test@test.com"); await userManager.AddToRoleAsync(user.Id, "Administrators"); } }
Il metodo EnsureAdministratorAsync ovviamente non è pensato per uno scenario di produzione, e non fa altro che assicurarsi dell'esistenza di un gruppo "Administrators" e della presenza, all'interno dello stesso, del nostro utente di test.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare database e servizi con gli add-on di Container App
Mascherare l'output di un valore all'interno dei log di un workflow di GitHub
Usare lo spread operator con i collection initializer in C#
Evitare la script injection nelle GitHub Actions
Eseguire una GroupBy per entity in Entity Framework
Utilizzare domini personalizzati gestiti automaticamente con Azure Container Apps
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Creare gruppi di client per Event Grid MQTT
Eseguire attività con Azure Container Jobs
Sfruttare lo streaming di una chiamata Http da Blazor
Usare le variabili per personalizzare gli stili CSS
Gestire errori funzionali tramite exception in ASP.NET Core Web API
I più letti di oggi
- annunciato #netstandard 2.1. .NET Core lo supporterà a partire da #netcore3, così come le prossime versione di #xamarin, #mono e #unity.il supporto per #netfx 4.8, invece, non ci sarà. https://aspit.co/bq2
- Annunciato Silverlight 4 RC e Windows Phone Developer Tools
- Speciale Razor: il nuovo view engine di WebMatrix e ASP.NET MVC
- Speciale Windows Store app: costruire app con WinRT per Windows 8
- Gestire lo stato all'interno di un class component di ReactJS
- Inserimenti bulk su database con la classe SqlBulkCopy di ADO.NET 2.0
- disponibile su MSDN la versione RTM di #VS2013 Update 2! https://aspit.co/auj #msTechEd