Autorização baseada em função no ASP.NET Core
Quando um identity é criado, ele pode pertencer a uma ou mais funções. Por exemplo, Tracy pode pertencer aos papéis Administrator
e User
, enquanto Scott pode pertencer apenas ao papel User
. A forma como essas funções são criadas e gerenciadas depende do armazenamento de suporte do processo de autorização. As funções são expostas ao desenvolvedor por meio do método IsInRole na classe ClaimsPrincipal.
AddRoles deve ser adicionado aos Serviços de Função.
Embora as funções sejam declarações, nem todas as declarações são funções. Dependendo do emissor identity, uma função pode ser uma coleção de utilizadores que podem fazer reivindicações para membros do grupo, bem como uma reivindicação real sobre um identity. No entanto, as declarações destinam-se a ser informações sobre um utilizador individual. Usar funções para adicionar declarações a um usuário pode confundir o limite entre o usuário e suas declarações individuais. Essa confusão é o motivo pelo qual os modelos de SPA não são projetados em torno de funções. Além disso, para organizações que migram de um sistema herdado local, a proliferação de funções ao longo dos anos pode significar que uma declaração de função pode ser muito grande para ser contida em um token utilizável por SPAs. Para proteger SPAs, consulte e utilize Identity para garantir um backend de API Web para SPAs.
Este artigo descreve a autorização baseada em função para aplicativos ASP.NET Core MVC e Razor. Para Blazor aplicativos, consulte ASP.NET de autenticação e autorização do Core Blazor e ASP.NET Core Blazor WebAssembly com grupos e funções do Microsoft Entra ID.
Adicionar serviços de função a Identity
Registre serviços de autorização baseados em função no Program.cs
chamando AddRoles com o tipo de função na configuração Identity do aplicativo. O tipo de função no exemplo a seguir é IdentityRole
:
builder.Services.AddDefaultIdentity<IdentityUser>( ... )
.AddRoles<IdentityRole>()
...
O código anterior requer o Microsoft.AspNetCore.Identity. UI pacote e uma diretiva using
para Microsoft.AspNetCore.Identity
.
Adicionando verificações de função
Verificações de autorização baseadas em função:
- São declarativos e especificam funções das quais o usuário atual deve ser membro para acessar o recurso solicitado.
- São aplicados a Razor Páginas, controladores ou ações dentro de um controlador.
- Os não podem ser aplicados no nível do manipulador de Página Razor, devem ser aplicados à Página.
Por exemplo, o código a seguir limita o acesso a quaisquer ações no AdministrationController
aos usuários que são membros da função Administrator
:
[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
public IActionResult Index() =>
Content("Administrator");
}
Várias funções podem ser especificadas como uma lista separada por vírgula:
[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
public IActionResult Payslip() =>
Content("HRManager || Finance");
}
O SalaryController
só é acessível por usuários que são membros da função HRManager
ou a função Finance
.
Quando vários atributos são aplicados, um usuário que acessa deve ser membro de de todas as funções especificadas. O exemplo a seguir requer que um usuário seja membro de funçãoPowerUser
eControlPanelUser
:
[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
public IActionResult Index() =>
Content("PowerUser && ControlPanelUser");
}
O acesso a uma ação pode ser limitado aplicando atributos de autorização de função adicionais no nível da ação:
[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
public IActionResult SetTime() =>
Content("Administrator || PowerUser");
[Authorize(Roles = "Administrator")]
public IActionResult ShutDown() =>
Content("Administrator only");
}
Na controladora ControlAllPanelController
precedente:
- Os membros da função
Administrator
ou da funçãoPowerUser
podem acessar o controlador e a açãoShutDown
. - Somente os membros da função
Administrator
podem acessar a açãoSetTime
.
Um controlador pode ser protegido, mas permitir acesso anônimo e não autenticado a ações individuais:
[Authorize]
public class Control3PanelController : Controller
{
public IActionResult SetTime() =>
Content("[Authorize]");
[AllowAnonymous]
public IActionResult Login() =>
Content("[AllowAnonymous]");
}
Para Razor Páginas, [Authorize]
pode ser aplicado de uma das seguintes formas:
- Usando uma convenção , ou
- Aplicação de
[Authorize]
na instânciaPageModel
.
[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
public IActionResult OnPost() =>
Content("OnPost RequireAdministratorRole");
}
Importante
Os atributos de filtro, incluindo AuthorizeAttribute
, só podem ser aplicados a PageModel e não podem ser aplicados a métodos específicos de manipulador de página.
Verificações de funções baseadas em políticas
Os requisitos de função também podem ser expressos usando a sintaxe Policy, onde um desenvolvedor registra uma política na inicialização do aplicativo como parte da configuração do serviço de Autorização. Isso normalmente ocorre no arquivo Program.cs
:
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();
As políticas são aplicadas usando a propriedade Policy no atributo [Authorize]
:
[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
return View();
}
Para especificar várias funções permitidas em um requisito, especifique-as como parâmetros para o método RequireRole:
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();
O código anterior autoriza os usuários que pertencem às funções Administrator
, PowerUser
ou BackupAdministrator
.
Quando um identity é criado, ele pode pertencer a uma ou mais funções. Por exemplo, Tracy pode pertencer às funções de Administrador e Utilizador, enquanto Scott só pode pertencer à função de Utilizador. A forma como essas funções são criadas e gerenciadas depende do armazenamento de suporte do processo de autorização. As funções são expostas ao desenvolvedor por meio do método IsInRole na classe ClaimsPrincipal.
Recomendamos não utilizar "Funções" como declarações, mas sim utilizar declarações. Ao usar aplicações de página única (SPAs), consulte utilizar Identity para proteger um back-end de API da web para SPAs.
Adicionando verificações de função
Verificações de autorização baseadas em função:
- São declarativos.
- São aplicados a Razor Páginas, controladores ou ações dentro de um controlador.
- Os não podem ser aplicados no nível do manipulador de Página Razor, devem ser aplicados à Página.
As verificações de autorização baseadas em função especificam quais funções o usuário atual deve ser membro para acessar o recurso solicitado.
Por exemplo, o código a seguir limita o acesso a quaisquer ações no AdministrationController
aos usuários que são membros da função Administrator
:
[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
public IActionResult Index() =>
Content("Administrator");
}
Várias funções podem ser especificadas como uma lista separada por vírgula:
[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
public IActionResult Payslip() =>
Content("HRManager || Finance");
}
O controlador SalaryController
só é acessível por utilizadores que são membros da função HRManager
ou a função Finance
.
Se você aplicar vários atributos, um usuário que estiver acessando deverá ser membro de todas as funções especificadas. O exemplo a seguir requer que um usuário seja membro da função PowerUser
e ControlPanelUser
:
[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
public IActionResult Index() =>
Content("PowerUser && ControlPanelUser");
}
Você pode limitar ainda mais o acesso aplicando atributos de autorização de função adicionais no nível da ação:
[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
public IActionResult SetTime() =>
Content("Administrator || PowerUser");
[Authorize(Roles = "Administrator")]
public IActionResult ShutDown() =>
Content("Administrator only");
}
Se vários atributos forem aplicados nos níveis de controlador e ação, todos os atributos deverão passar antes que o acesso seja concedido:
[Authorize(Roles = "Administrator")]
public class ControlAllPanelController2 : Controller
{
public IActionResult SetTime() =>
Content("Administrator only");
[Authorize(Roles = "PowerUser")]
public IActionResult ShutDown() =>
Content("Administrator && PowerUser");
}
Na controladora ControlAllPanelController
precedente:
- Os membros da função
Administrator
ou da funçãoPowerUser
podem acessar o controlador e a açãoSetTime
. - Somente os membros da função
Administrator
podem acessar a açãoShutDown
.
Você também pode bloquear um controlador, mas permitir acesso anônimo e não autenticado a ações individuais.
[Authorize]
public class Control3PanelController : Controller
{
public IActionResult SetTime() =>
Content("[Authorize]");
[AllowAnonymous]
public IActionResult Login() =>
Content("[AllowAnonymous]");
}
Para Razor Páginas, o [Authorize]
pode ser aplicado por:
- Usando uma convenção , ou
- Aplicando o
[Authorize]
à instânciaPageModel
.
[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
public ActionResult OnPost()
{
}
}
Importante
Os atributos de filtro, incluindo AuthorizeAttribute
, só podem ser aplicados a PageModel e não podem ser aplicados a métodos específicos de manipulador de página.
Verificações de funções baseadas em políticas
Os requisitos de função também podem ser expressos usando a nova sintaxe Política, onde um desenvolvedor registra uma política na inicialização como parte da configuração do serviço de Autorização. Isso normalmente ocorre em ConfigureServices()
no seu ficheiro Startup.cs
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdministratorRole",
policy => policy.RequireRole("Administrator"));
});
}
As políticas são aplicadas usando a propriedade Policy
no atributo [Authorize]
:
[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
return View();
}
Se você quiser especificar várias funções permitidas em um requisito, poderá especificá-las como parâmetros para o método RequireRole
:
options.AddPolicy("ElevatedRights", policy =>
policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));
Este exemplo autoriza os usuários que pertencem às funções Administrator
, PowerUser
ou BackupAdministrator
.
Adicionar serviços de função a Identity
Anexe AddRoles para adicionar serviços de função:
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();
}