Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Cuando se crea una identidad para un usuario de aplicación al iniciar sesión en una aplicación, el proveedor de identidades puede asignar una o varias notificaciones a la identidad del usuario. Una declaración es un par nombre-valor que representa lo que el sujeto (un usuario, una aplicación o servicio, o un dispositivo o equipo) es, no lo que el sujeto puede hacer. La aplicación puede evaluar una notificación para determinar los derechos de acceso a los datos y otros recursos protegidos durante el proceso de autorización y también se puede usar para tomar o expresar decisiones de autenticación sobre un sujeto. Una identidad puede contener múltiples declaraciones con múltiples valores y puede contener múltiples declaraciones del mismo tipo. En este artículo se explica cómo agregar verificaciones de declaraciones para la autorización en una aplicación de ASP.NET Core.
En este artículo se usan Razor ejemplos de componentes y se centra en Blazor escenarios de autorización. Para obtener instrucciones adicionales Blazor , consulte la sección Contenido relacionado . Para obtener instrucciones de Razor Pages y MVC, consulte los siguientes recursos:
- Autorización basada en reclamaciones en Razor
- Autorización basada en reclamación en ASP.NET Core MVC
Aplicación de ejemplo
El ejemplo de Blazor Web App para este artículo es la aplicación de ejemplo BlazorWebAppAuthorization (dotnet/AspNetCore.Docs.Samples GitHub repository) (how to download). La aplicación de ejemplo utiliza cuentas inicializadas con reclamaciones preconfiguradas para ilustrar la mayoría de los ejemplos de este artículo. Para obtener más información, consulte el archivo LÉAME del ejemplo (README.md).
Precaución
Esta aplicación de ejemplo usa una base de datos en memoria para almacenar información de usuario, que no es adecuada para escenarios de producción. La aplicación de ejemplo está pensada solo para fines de demostración y no debe usarse como punto de partida para las aplicaciones de producción.
Añadir comprobaciones de reclamaciones
Comprobaciones de autorización basadas en reclamaciones
- Las políticas son declarativas y especifican las reclamaciones que el usuario actual debe presentar para acceder al recurso solicitado.
- Se aplican a componentes de Razor (ejemplos de este artículo), Razor Pages o controladores MVC o acciones dentro de un controlador.
El componente de AuthorizeView (componente de AuthorizeView en la documentación de Blazor) admite la autorización basada en directivas, donde la directiva requiere una o varias reclamaciones. Como alternativa, se puede configurar una autorización basada en declaraciones mediante una o más comprobaciones de políticas usando atributos [Authorize] en componentes Razor. El desarrollador debe compilar y registrar una directiva que exprese los requisitos de notificaciones. En esta sección se tratan los conceptos básicos. Para obtener cobertura completa, consulte ASP.NET Core Blazor autenticación y autorización.
El tipo más sencillo de política de reclamaciones busca la presencia de una reclamación y no verifica su valor.
El registro de la directiva tiene lugar como parte de la configuración del servicio de autorización en el archivo de Program la aplicación:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
Nota:
WebApplicationBuilder.ConfigureApplication (reference source) agrega automáticamente una llamada a UseAuthorization cuando se registra IAuthorizationHandlerProvider, que ha sido el comportamiento de ASP.NET Core desde la publicación de .NET 8. Por lo tanto, llamar a UseAuthorization explícitamente para aplicaciones de Blazor del lado servidor en .NET 8 o posterior es técnicamente redundante, pero la llamada no es perjudicial. Si se llama en el código del desarrollador después de que el marco ya lo haya llamado, básicamente no tiene ningún efecto.
Nota:
Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta para una versión específica, use la lista desplegable Cambiar ramas o etiquetas .
El registro de la directiva tiene lugar como parte de la configuración del servicio de autorización en el archivo de Program la aplicación:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
En las aplicaciones de Blazor Server, llame a UseAuthorization después de la línea que llama a UseAuthentication (si está presente):
app.UseAuthentication(); // Only present if not called internally
app.UseAuthorization();
El registro de la directiva tiene lugar como parte de la configuración del servicio de autorización en Startup.ConfigureServices (Startup.cs):
services.AddAuthorization(options =>
{
options.AddPolicy("EmployeeOnly", policy =>
policy.RequireClaim("EmployeeNumber"));
});
En las aplicaciones de Blazor Server, llame a UseAuthorization en Startup.Configure después de la línea que llama a UseAuthentication (si está presente):
app.UseAuthentication(); // Only present if not called internally
app.UseAuthorization();
Las aplicaciones de Blazor WebAssembly llaman a AddAuthorizationCore en el archivo Program para agregar servicios de autorización:
builder.Services.AddAuthorizationCore();
Aplique la directiva mediante la Policy propiedad en el [Authorize] atributo para especificar el nombre de la directiva. En el ejemplo siguiente, la directiva EmployeeOnly comprueba la presencia de una reclamación de EmployeeNumber en la identidad actual.
Para la autorización basada en directivas mediante un AuthorizeView componente, use el AuthorizeView.Policy parámetro con un nombre de directiva único.
Pages/PassEmployeeOnlyPolicyWithAuthorizeView.razor:
@page "/pass-employeeonly-policy-with-authorizeview"
<h1>Pass 'EmployeeOnly' policy with AuthorizeView</h1>
<AuthorizeView Policy="EmployeeOnly">
<Authorized>
<p>You satisfy the 'EmployeeOnly' policy.</p>
</Authorized>
<NotAuthorized>
<p>You <b>don't</b> satisfy the 'EmployeeOnly' policy.</p>
</NotAuthorized>
</AuthorizeView>
Como alternativa, aplique la directiva mediante la Policy propiedad en el [Authorize] atributo para especificar el nombre de la directiva. En el ejemplo siguiente, la directiva EmployeeOnly comprueba la presencia de una reclamación de EmployeeNumber en la identidad actual.
Pages/PassEmployeeOnlyPolicyWithAuthorizeAttribute.razor:
@page "/pass-employeeonly-policy-with-authorize-attribute"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EmployeeOnly")]
<h1>Pass 'EmployeeOnly' policy with [Authorize] attribute</h1>
<p>You satisfy the 'EmployeeOnly' policy.</p>
Puede especificar una lista de valores permitidos al crear una directiva. La siguiente directiva aplica solo a los empleados cuyo número de empleado es 1, 2, 3, 4 o 5:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthorizationBuilder()
.AddPolicy("Founders", policy =>
policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
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();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("Founders", policy =>
policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
});
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();
services.AddAuthorization(options =>
{
options.AddPolicy("Founder", policy =>
policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
});
Pages/PassFounderPolicyWithAuthorizeView.razor:
@page "/pass-founder-policy-with-authorizeview"
<h1>Pass 'Founder' policy with AuthorizeView</h1>
<AuthorizeView Policy="Founder">
<Authorized>
<p>You satisfy the 'Founder' policy.</p>
</Authorized>
<NotAuthorized>
<p>You <b>don't</b> satisfy the 'Founder' policy.</p>
</NotAuthorized>
</AuthorizeView>
Agregar una comprobación de notificación genérica
Si el valor de la notificación no es un valor único o necesita una lógica de evaluación de notificaciones más flexible, como la coincidencia de patrones, la comprobación del emisor de notificaciones o el análisis de valores de notificación complejos, use RequireAssertion con HasClaim. Por ejemplo, la siguiente política requiere que la declaración del email usuario termine con un dominio específico.
builder.Services.AddAuthorizationBuilder()
.AddPolicy("ContosoOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "email" &&
c.Value.EndsWith("@contoso.com", StringComparison.OrdinalIgnoreCase))));
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ContosoOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "email" &&
c.Value.EndsWith("@contoso.com", StringComparison.OrdinalIgnoreCase))));
});
services.AddAuthorization(options =>
{
options.AddPolicy("ContosoOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "email" &&
c.Value.EndsWith("@contoso.com", StringComparison.OrdinalIgnoreCase))));
});
Para obtener más información, vea Autorización basada en directivas en ASP.NET Core.
Evaluación de varias directivas
Se aplican varias directivas a través de varios AuthorizeView componentes. El componente interno requiere que el usuario pase su directiva y cada directiva de componentes primarios de AuthorizeView.
En el ejemplo siguiente:
- Requiere una directiva
CustomerServiceMember, que indica que el usuario está en el departamento de atención al cliente de la organización porque tiene una reclamación deDepartmentcon un valor deCustomer Service. - También requiere una directiva
HumanResourcesMember, que indica que el usuario está en el departamento de recursos humanos de la organización porque tiene una reclamación deDepartmentcon un valor deHuman Resources.
En el archivo Program de la aplicación:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("CustomerServiceMember", policy =>
policy.RequireClaim("Department", "Customer Service"))
.AddPolicy("HumanResourcesMember", policy =>
policy.RequireClaim("Department", "Human Resources"));
En el archivo Program de la aplicación:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CustomerServiceMember", policy =>
policy.RequireClaim("Department", "Customer Service"));
options.AddPolicy("HumanResourcesMember", policy =>
policy.RequireClaim("Department", "Human Resources"));
});
En Startup.ConfigureServices (Startup.cs):
services.AddAuthorization(options =>
{
options.AddPolicy("CustomerServiceMember", policy =>
policy.RequireClaim("Department", "Customer Service"));
options.AddPolicy("HumanResourcesMember", policy =>
policy.RequireClaim("Department", "Human Resources"));
});
En el ejemplo siguiente se usan AuthorizeView componentes.
Pages/PassCustomerServiceMemberAndHumanResourcesMemberPoliciesWithAuthorizeViews.razor:
@page "/pass-customerservicemember-and-humanresourcesmember-policies-with-authorizeviews"
<h1>Pass 'CustomerServiceMember' and 'HumanResourcesMember' policies with AuthorizeViews</h1>
<AuthorizeView Policy="CustomerServiceMember">
<Authorized>
<p>User: @context.User.Identity?.Name</p>
<AuthorizeView Policy="HumanResourcesMember" Context="innerContext">
<Authorized>
<p>
You satisfy the 'CustomerServiceMember' and 'HumanResourcesMember' policies.
</p>
</Authorized>
<NotAuthorized>
<p>
You satisfy the 'CustomerServiceMember' policy, but you <b>don't</b> satisfy
the 'HumanResourcesMember' policy.
</p>
</NotAuthorized>
</AuthorizeView>
</Authorized>
<NotAuthorized>
<p>
You <b>don't</b> satisfy the 'CustomerServiceMember' policy.
</p>
</NotAuthorized>
</AuthorizeView>
En el ejemplo siguiente se usan [Authorize] atributos.
Pages/PassCustomerServiceMemberAndHumanResourcesMemberPoliciesWithAuthorizeAttributes.razor:
@page "/pass-customerservicemember-and-humanresourcesmember-policies-with-authorize-attributes"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "CustomerServiceMember")]
@attribute [Authorize(Policy = "HumanResourcesMember")]
<h1>
Pass 'CustomerServiceMember' and 'HumanResourcesMember' policies with [Authorize] attributes
</h1>
<p>
You satisfy the 'CustomerServiceMember' and 'HumanResourcesMember' policies.
</p>
Para directivas más complicadas, como tomar una fecha de nacimiento, calcular una edad a partir de ella, comprobar que la edad es de 21 o más, usar RequireAssertion o escribir controladores de directivas personalizados. Los controladores de políticas personalizados son útiles cuando se necesita acceso a servicios inyectados por dependencias o si desea un componente de autorización reutilizable y verificable.
Distinción entre mayúsculas y minúsculas en las reclamaciones
Los valores de reclamación se comparan mediante StringComparison.Ordinal. Esto significa que Admin (en mayúsculas A) y admin (en minúsculas a) siempre se consideran roles diferentes, independientemente del controlador de autenticación que creó la identidad.
Por otra parte, la comparación del tipo de reclamación (que se utiliza para localizar reclamaciones de rol por su tipo, como http://schemas.microsoft.com/ws/2008/06/identity/claims/role) puede distinguir o no entre mayúsculas y minúsculas, dependiendo de la implementación de ClaimsIdentity. Con Microsoft.IdentityModel en ASP.NET Core 8.0 o versión posterior (que usan AddJwtBearer, AddOpenIdConnect, AddWsFederation y AddMicrosoftIdentityWebApp/AddMicrosoftIdentityWebApi), CaseSensitiveClaimsIdentity se genera durante la validación de tókenes, que utiliza una coincidencia de tipos de reclamación que distingue entre mayúsculas y minúsculas.
La ClaimsIdentity predeterminada proporcionada por el entorno de ejecución de .NET (que se usa en la mayoría de los casos, incluidos todos los flujos basados en cookie) sigue utilizando coincidencias de tipos de reclamación que no distinguen entre mayúsculas y minúsculas.
En la práctica, esta distinción rara vez tiene importancia para la autorización basada en roles, ya que el tipo de reclamación de rol se establece una sola vez durante la creación de la identidad y se aplica de forma coherente. Utilice siempre las mismas mayúsculas y minúsculas en los nombres de los roles y los tipos de reclamaciones para evitar problemas sutiles.
Contenido relacionado
- ASP.NET Core Blazor autenticación y autorización
- ASP.NET Core Blazor estado de autenticación
- ASP.NET Core Blazor WebAssembly escenarios de seguridad adicionales
- Usa Graph API con ASP.NET Core Blazor WebAssembly
- Protección segura de ASP.NET CoreBlazor WebAssembly
- Autorización basada en reclamaciones en Razor
- Autorización basada en reclamación en ASP.NET Core MVC
-
Extender o agregar declaraciones personalizadas, incluidas las declaraciones de rol, mediante
IClaimsTransformation