Asignación, personalización y transformación de notificaciones en ASP.NET Core
Las notificaciones se pueden crear a partir de cualquier usuario o datos de identidad que se puedan emitir mediante un proveedor de identidades de confianza o de una identidad de ASP.NET Core. Una notificación es un par de valor y nombre que representa lo que es el sujeto, no lo que puede hacer. En este artículo se detallan las siguientes áreas:
- Configuración y asignación de notificaciones mediante un cliente de OpenID Connect
- Establecimiento del nombre y la notificación de rol
- Restablecimiento de los espacios de nombres de notificaciones
- Personalización, ampliación de las notificaciones con TransformAsync
Asignación de notificaciones mediante la autenticación de OpenID Connect
Las notificaciones de perfil se pueden devolver en id_token
, que se devuelve después de una autenticación correcta. La aplicación cliente ASP.NET Core solo requiere el ámbito del perfil. Cuando se usa id_token
para notificaciones, no se requiere ninguna asignación de notificaciones adicional.
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
El código anterior requiere el paquete NuGet Microsoft.AspNetCore.Authentication.OpenIdConnect.
Otra manera de obtener las notificaciones del usuario es usar la API de información de usuario de OpenID Connect. La aplicación cliente ASP.NET Core usa la propiedad GetClaimsFromUserInfoEndpoint
para configurarlo. Una diferencia importante de la primera configuración es que debe especificar las notificaciones que necesita mediante el método MapUniqueJsonKey
; de lo contrario, solo las notificaciones estándar name
, given_name
y email
estarán disponibles en la aplicación cliente. Las notificaciones incluidas en id_token
se asignan por valor predeterminado. Esta es la principal diferencia con la primera opción. Debe definir explícitamente algunas de las notificaciones que necesite.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapUniqueJsonKey("preferred_username",
"preferred_username");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
});
var app = builder.Build();
// Code removed for brevity.
Nota:
El controlador de Open ID Connect predeterminado usa solicitudes de autorización push (PAR) si el documento de detección del proveedor de identidades anuncia la compatibilidad con PAR. El documento de detección del proveedor de identidades se encuentra normalmente en .well-known/openid-configuration
. Si no puede usar PAR en la configuración del cliente en el proveedor de identidades, PAR se puede deshabilitar mediante la opción PushedAuthorizationBehavior.
builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("oidc", oidcOptions =>
{
// Other provider-specific configuration goes here.
// The default value is PushedAuthorizationBehavior.UseIfAvailable.
// 'OpenIdConnectOptions' does not contain a definition for 'PushedAuthorizationBehavior'
// and no accessible extension method 'PushedAuthorizationBehavior' accepting a first argument
// of type 'OpenIdConnectOptions' could be found
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
});
Para asegurarte de que la autenticación solo se realiza correctamente si se usa PAR, usa PushedAuthorizationBehavior.Require en su lugar. Este cambio también presenta un nuevo evento OnPushAuthorization a OpenIdConnectEvents que se puede usar para personalizar la solicitud de autorización lanzada o controlarla manualmente. Consulta la propuesta de API para obtener más detalles.
Asignación de notificaciones de nombre y notificación de rol
La notificación Name y la notificación Role se asignan a las propiedades predeterminadas en el contexto HTTP de ASP.NET Core. A veces es necesario usar diferentes notificaciones para las propiedades predeterminadas, o la notificación de nombre y la notificación de rol no coinciden con los valores predeterminados. Las notificaciones se pueden asignar mediante la propiedad TokenValidationParameters y establecerse en cualquier notificación según sea necesario. Los valores de las notificaciones se pueden usar directamente en la propiedad HttpContext User.Identity.Name y los roles.
Si User.Identity.Name
no tiene ningún valor o faltan los roles, compruebe los valores de las notificaciones devueltas y establezca NameClaimType
y los valores RoleClaimType
. Las notificaciones devueltas de la autenticación de cliente se pueden ver en el contexto HTTP.
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// Other options...
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "email"
//, RoleClaimType = "role"
};
});
Espacios de nombres de notificaciones, espacios de nombres predeterminados
ASP.NET Core agrega espacios de nombres predeterminados a algunas notificaciones conocidas, lo que podría no ser necesario en la aplicación. Opcionalmente, deshabilite estos espacios de nombres agregados y use las notificaciones exactas que creó el servidor OpenID Connect.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
Si necesita deshabilitar los espacios de nombres por esquema y no globalmente, puede usar la opción MapInboundClaims = false.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.MapInboundClaims = false;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
Extensión o adición de notificaciones personalizadas con IClaimsTransformation
La interfaz IClaimsTransformation se puede usar para agregar notificaciones adicionales a la clase ClaimsPrincipal. La interfaz requiere un único método TransformAsync. Este método puede llamarse varias veces. Agregue solo una nueva notificación si aún no existe en ClaimsPrincipal
. ClaimsIdentity
se crea para agregar las nuevas notificaciones y se puede agregar a ClaimsPrincipal
.
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
La interfaz IClaimsTransformation y la clase MyClaimsTransformation
se pueden registrar como un servicio:
builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Asignación de notificaciones de proveedores de identidades externos
Consulte el documento siguiente:
Conservar notificaciones y tokens adicionales de proveedores externos en ASP.NET Core
Las notificaciones se pueden crear a partir de cualquier usuario o datos de identidad que se puedan emitir mediante un proveedor de identidades de confianza o de una identidad de ASP.NET Core. Una notificación es un par de valor y nombre que representa lo que es el sujeto, no lo que puede hacer. En este artículo se detallan las siguientes áreas:
- Configuración y asignación de notificaciones mediante un cliente de OpenID Connect
- Establecimiento del nombre y la notificación de rol
- Restablecimiento de los espacios de nombres de notificaciones
- Personalización, ampliación de las notificaciones con TransformAsync
Asignación de notificaciones mediante la autenticación de OpenID Connect
Las notificaciones de perfil se pueden devolver en id_token
, que se devuelve después de una autenticación correcta. La aplicación cliente ASP.NET Core solo requiere el ámbito del perfil. Cuando se usa id_token
para notificaciones, no se requiere ninguna asignación de notificaciones adicional.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
Otra manera de obtener las notificaciones del usuario es usar la API de información de usuario de OpenID Connect. La aplicación cliente ASP.NET Core usa la propiedad GetClaimsFromUserInfoEndpoint
para configurarlo. Una diferencia importante de la primera configuración es que debe especificar las notificaciones que necesita mediante el método MapUniqueJsonKey
; de lo contrario, solo las notificaciones estándar name
, given_name
y email
estarán disponibles en la aplicación cliente. Las notificaciones incluidas en id_token
se asignan por valor predeterminado. Esta es la principal diferencia con la primera opción. Debe definir explícitamente algunas de las notificaciones que necesite.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapUniqueJsonKey("preferred_username", "preferred_username");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
});
Asignación de notificaciones de nombre y notificación de rol
La notificación Name y la notificación Role se asignan a las propiedades predeterminadas en el contexto HTTP de ASP.NET Core. A veces es necesario usar diferentes notificaciones para las propiedades predeterminadas, o la notificación de nombre y la notificación de rol no coinciden con los valores predeterminados. Las notificaciones se pueden asignar mediante la propiedad TokenValidationParameters y establecerse en cualquier notificación según sea necesario. Los valores de las notificaciones se pueden usar directamente en la propiedad HttpContext User.Identity.Name y los roles.
Si User.Identity.Name
no tiene ningún valor o faltan los roles, compruebe los valores de las notificaciones devueltas y establezca NameClaimType
y los valores RoleClaimType
. Las notificaciones devueltas de la autenticación de cliente se pueden ver en el contexto HTTP.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// other options...
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "email",
// RoleClaimType = "role"
};
});
Espacios de nombres de notificaciones, espacios de nombres predeterminados
ASP.NET Core agrega espacios de nombres predeterminados a algunas notificaciones conocidas, lo que podría no ser necesario en la aplicación. Opcionalmente, deshabilite estos espacios de nombres agregados y use las notificaciones exactas que creó el servidor OpenID Connect.
public void Configure(IApplicationBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
Extensión o adición de notificaciones personalizadas con IClaimsTransformation
La interfaz IClaimsTransformation
se puede usar para agregar notificaciones adicionales a la clase ClaimsPrincipal
. La interfaz requiere un único método TransformAsync
. Este método puede llamarse varias veces. Agregue solo una nueva notificación si aún no existe en ClaimsPrincipal
. ClaimsIdentity
se crea para agregar las nuevas notificaciones y se puede agregar a ClaimsPrincipal
.
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
La interfaz IClaimsTransformation
y la clase MyClaimsTransformation
se pueden agregar en el método ConfigureServices como servicio.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Extender o agregar notificaciones personalizadas en ASP.NET Core Identity
Consulte el documento siguiente:
Adición de notificaciones a Identity con IUserClaimsPrincipalFactory
Asignación de notificaciones de proveedores de identidades externos
Consulte el documento siguiente:
Conservar notificaciones y tokens adicionales de proveedores externos en ASP.NET Core