Autorizzazione basata sui ruoli in ASP.NET Core

Quando viene creata un'identità, può appartenere a uno o più ruoli. Ad esempio, Tracy può appartenere ai Administrator ruoli e User mentre Scott può appartenere solo al User ruolo. La modalità di creazione e gestione di questi ruoli dipende dall'archivio di backup del processo di autorizzazione. I ruoli vengono esposti allo sviluppatore tramite il IsInRole metodo nella ClaimsPrincipal classe . AddRoles deve essere aggiunto ai servizi ruolo.

Mentre i ruoli sono attestazioni, non tutte le attestazioni sono ruoli. A seconda dell'autorità emittente dell'identità, un ruolo può essere una raccolta di utenti che possono applicare attestazioni per i membri del gruppo, nonché un'attestazione effettiva su un'identità. Tuttavia, le attestazioni devono essere informazioni su un singolo utente. L'uso dei ruoli per aggiungere attestazioni a un utente può confondere il limite tra l'utente e le singole attestazioni. Questa confusione è il motivo per cui i modelli spa non sono progettati per i ruoli. Inoltre, per le organizzazioni che eseguono la migrazione da un sistema legacy locale, la proliferazione dei ruoli nel corso degli anni può significare che un'attestazione di ruolo può essere troppo grande per essere contenuta all'interno di un token utilizzabile dalle autorità di servizio. Per proteggere le applicazioni a pagina singola, vedere Usare Identity per proteggere un back-end dell'API Web per le applicazioni a pagina singola.

Aggiungere servizi ruolo a Identity

Registrare i servizi di autorizzazione basati sui ruoli in Program.cs chiamando AddRoles con il tipo di ruolo nella configurazione dell'app Identity . Il tipo di ruolo nell'esempio seguente è IdentityRole:

builder.Services.AddDefaultIdentity<IdentityUser>( ... )
    .AddRoles<IdentityRole>()
    ...

Il codice precedente richiede Microsoft.AspNetCore.Identity. Pacchetto dell'interfaccia utente e direttiva using per Microsoft.AspNetCore.Identity.

Aggiunta di controlli dei ruoli

Controlli di autorizzazione basati sui ruoli:

  • Sono dichiarativi e specificano i ruoli di cui l'utente corrente deve essere membro per accedere alla risorsa richiesta.
  • Vengono applicate a Razor Pagine, controller o azioni all'interno di un controller.
  • Non può essere applicato a livello di Razor gestore pagina, ma deve essere applicato alla pagina.

Ad esempio, il codice seguente limita l'accesso a qualsiasi azione per AdministrationController gli utenti membri del Administrator ruolo:

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
    public IActionResult Index() =>
        Content("Administrator");
}

È possibile specificare più ruoli come elenco delimitato da virgole:

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
    public IActionResult Payslip() =>
                    Content("HRManager || Finance");
}

SalaryController è accessibile solo dagli utenti membri del HRManager ruolo o del Finance ruolo.

Quando vengono applicati più attributi, un utente che accede deve essere membro di tutti i ruoli specificati. L'esempio seguente richiede che un utente sia membro del PowerUserruolo e :ControlPanelUser

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
    public IActionResult Index() =>
        Content("PowerUser && ControlPanelUser");
}

L'accesso a un'azione può essere limitato applicando altri attributi di autorizzazione del ruolo a livello di azione:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator || PowerUser");

    [Authorize(Roles = "Administrator")]
    public IActionResult ShutDown() =>
        Content("Administrator only");
}

Nel controller precedente ControlAllPanelController :

  • I membri del Administrator ruolo o del PowerUser ruolo possono accedere al controller e all'azione SetTime .
  • Solo i membri del Administrator ruolo possono accedere all'azione ShutDown .

Un controller può essere bloccato ma consente l'accesso anonimo e non autenticato alle singole azioni:

[Authorize]
public class Control3PanelController : Controller
{
    public IActionResult SetTime() =>
        Content("[Authorize]");

    [AllowAnonymous]
    public IActionResult Login() =>
        Content("[AllowAnonymous]");
}

Per Razor Pages, [Authorize] può essere applicato in uno dei due casi seguenti:

[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
    public IActionResult OnPost() =>
         Content("OnPost RequireAdministratorRole");
}

Importante

Gli attributi di filtro, incluso AuthorizeAttribute, possono essere applicati solo a PageModel e non possono essere applicati a metodi specifici del gestore di pagine.

Controlli dei ruoli basati su criteri

I requisiti dei ruoli possono essere espressi anche usando la sintassi Dei criteri, in cui uno sviluppatore registra un criterio all'avvio dell'applicazione come parte della configurazione del servizio di autorizzazione. Questo si verifica in genere nel Program.cs file:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdministratorRole",
         policy => policy.RequireRole("Administrator"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

I criteri vengono applicati usando la Policy proprietà sull'attributo [Authorize] :

[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
    return View();
}

Per specificare più ruoli consentiti in un requisito, specificarli come parametri per il RequireRole metodo :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("ElevatedRights", policy =>
          policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));
});

var app = builder.Build();

Il codice precedente autorizza gli utenti che appartengono ai Administratorruoli o PowerUserBackupAdministrator .

Quando viene creata un'identità, può appartenere a uno o più ruoli. Ad esempio, Tracy può appartenere ai ruoli Amministrazione istrator e Utente, mentre Scott può appartenere solo al ruolo Utente. La modalità di creazione e gestione di questi ruoli dipende dall'archivio di backup del processo di autorizzazione. I ruoli vengono esposti allo sviluppatore tramite il IsInRole metodo nella ClaimsPrincipal classe .

È consigliabile non usare Ruoli come attestazioni, ma piuttosto usare attestazioni. Quando si usano app a pagina singola, vedere Usare Identity per proteggere un back-end dell'API Web per le app a pagina singola.

Aggiunta di controlli dei ruoli

Controlli di autorizzazione basati sui ruoli:

  • Sono dichiarativi.
  • Vengono applicate a Razor Pagine, controller o azioni all'interno di un controller.
  • Non può essere applicato a livello di Razor gestore pagina, ma deve essere applicato alla pagina.

I controlli di autorizzazione basati sui ruoli specificano quali ruoli devono essere membri dell'utente corrente per accedere alla risorsa richiesta.

Ad esempio, il codice seguente limita l'accesso a qualsiasi azione per AdministrationController gli utenti membri del Administrator ruolo:

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
    public IActionResult Index() =>
        Content("Administrator");
}

È possibile specificare più ruoli come elenco delimitato da virgole:

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
    public IActionResult Payslip() =>
                    Content("HRManager || Finance");
}

Il controller SalaryController è accessibile solo dagli utenti membri del HRManager ruolo o del Finance ruolo.

Se si applicano più attributi, un utente che accede deve essere membro di tutti i ruoli specificati. L'esempio seguente richiede che un utente sia membro del PowerUser ruolo e ControlPanelUser :

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
    public IActionResult Index() =>
        Content("PowerUser && ControlPanelUser");
}

È possibile limitare ulteriormente l'accesso applicando altri attributi di autorizzazione del ruolo a livello di azione:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator || PowerUser");

    [Authorize(Roles = "Administrator")]
    public IActionResult ShutDown() =>
        Content("Administrator only");
}

Se vengono applicati più attributi a livello di controller e azione, tutti gli attributi devono essere passati prima che venga concesso l'accesso:

[Authorize(Roles = "Administrator")]
public class ControlAllPanelController2 : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator only");

    [Authorize(Roles = "PowerUser")]
    public IActionResult ShutDown() =>
        Content("Administrator && PowerUser");
}

Nel controller precedente ControlAllPanelController :

  • I membri del Administrator ruolo o del PowerUser ruolo possono accedere al controller e all'azione SetTime .
  • Solo i membri del Administrator ruolo possono accedere all'azione ShutDown .

È anche possibile bloccare un controller, ma consentire l'accesso anonimo non autenticato alle singole azioni.

[Authorize]
public class Control3PanelController : Controller
{
    public IActionResult SetTime() =>
        Content("[Authorize]");

    [AllowAnonymous]
    public IActionResult Login() =>
        Content("[AllowAnonymous]");
}

Per Razor Pages, l'oggetto [Authorize] può essere applicato da:

[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
    public ActionResult OnPost()
    {
    }
}

Importante

Gli attributi di filtro, incluso AuthorizeAttribute, possono essere applicati solo a PageModel e non possono essere applicati a metodi specifici del gestore di pagine.

Controlli dei ruoli basati su criteri

I requisiti dei ruoli possono essere espressi anche usando la nuova sintassi dei criteri, in cui uno sviluppatore registra un criterio all'avvio come parte della configurazione del servizio di autorizzazione. Questo avviene normalmente nel ConfigureServices()Startup.cs file.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireAdministratorRole",
             policy => policy.RequireRole("Administrator"));
    });
}

I criteri vengono applicati usando la Policy proprietà sull'attributo [Authorize]:

[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
    return View();
}

Se si desidera specificare più ruoli consentiti in un requisito, è possibile specificarli come parametri per il RequireRole metodo :

options.AddPolicy("ElevatedRights", policy =>
                  policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));

Questo esempio autorizza gli utenti che appartengono ai Administratorruoli o PowerUserBackupAdministrator .

Aggiungere servizi ruolo a Identity

Aggiungere AddRoles per aggiungere servizi ruolo:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
    services.AddRazorPages();
}