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.
Sugerencia
Este contenido es un extracto del libro electrónico, ".NET Microservices Architecture for Containerized .NET Applications" (Arquitectura de microservicios de .NET para aplicaciones de .NET contenedorizadas), disponible en Documentación de .NET o como un PDF descargable y gratuito que se puede leer sin conexión.
Hay tantos aspectos sobre la seguridad en microservicios y aplicaciones web que el tema podría tomar fácilmente varios libros como este. Por lo tanto, en esta sección, nos centraremos en la autenticación, autorización y secretos de aplicación.
Implementación de la autenticación en microservicios y aplicaciones web de .NET
A menudo es necesario que los recursos y las API publicados por un servicio se limite a determinados usuarios o clientes de confianza. El primer paso para tomar estas decisiones de confianza de nivel de API es la autenticación. La autenticación es el proceso de comprobar de forma confiable la identidad de un usuario.
Cuando hay microservicios, la autenticación normalmente se controla de forma centralizada. Si usa una puerta de enlace de API, la puerta de enlace es un buen lugar para autenticarse, como se muestra en la figura 9-1. Si usa este enfoque, asegúrese de que no se puede acceder directamente a los microservicios individuales (sin la puerta de enlace de API), a menos que haya seguridad adicional para autenticar mensajes tanto si proceden de la puerta de enlace como si no.
Figura 9-1. Autenticación centralizada con una puerta de enlace de API
Cuando la puerta de enlace de API centraliza la autenticación, agrega información de usuario al reenviar solicitudes a los microservicios. Si se puede acceder directamente a los servicios, se puede usar un servicio de autenticación como Azure Active Directory o un microservicio de autenticación dedicado que actúe como servicio de token de seguridad (STS) para autenticar a los usuarios. Las decisiones de confianza se comparten entre los servicios con tokens de seguridad o cookies. (Estos tokens se pueden compartir entre ASP.NET aplicaciones core, si es necesario, mediante la implementación de uso compartido de cookies). Este patrón se muestra en la figura 9-2.
Figura 9-2. Autenticación por microservicio de identidad; trust se comparte mediante un token de autorización
Cuando se accede directamente a los microservicios, la confianza, que incluye la autenticación y la autorización, se controla mediante un token de seguridad emitido por un microservicio dedicado, compartido entre microservicios.
Autenticación con ASP.NET Core Identity
El mecanismo principal de ASP.NET Core para identificar a los usuarios de una aplicación es el sistema de pertenencia ASP.NET Core Identity . Identity de ASP.NET Core almacena información de usuario (incluida la información de inicio de sesión, roles y notificaciones) en un almacén de datos configurado por el desarrollador. Normalmente, el almacén de datos de ASP.NET Core Identity es un almacén de Entity Framework proporcionado en el Microsoft.AspNetCore.Identity.EntityFrameworkCore
paquete. Sin embargo, los almacenes personalizados u otros paquetes de terceros se pueden usar para almacenar información de identidad en Azure Table Storage, CosmosDB u otras ubicaciones.
Sugerencia
ASP.NET Core 2.1 y versiones posteriores proporciona ASP.NET Core Identity como biblioteca de clases de Razor, por lo que no verá gran parte del código necesario en el proyecto, como era el caso de las versiones anteriores. Para más información sobre cómo personalizar el código de identidad para satisfacer sus necesidades, consulte Scaffold Identity in ASP.NET Core projects.
El código siguiente se toma de la plantilla de proyecto ASP.NET Core Web Application MVC con la autenticación de cuenta de usuario individual seleccionada. Muestra cómo configurar ASP.NET Core Identity mediante Entity Framework Core en el archivo Program.cs .
//...
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
//...
Una vez configurada ASP.NET Core Identity, habilítela agregando los app.UseAuthentication()
y endpoints.MapRazorPages()
como se muestra en el código siguiente en el archivo Program.cs del servicio:
//...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
//...
Importante
Las líneas del código anterior DEBEN ESTAR EN EL ORDEN MOSTRADO para que la identidad funcione correctamente.
El uso de ASP.NET Core Identity habilita varios escenarios:
Cree nueva información de usuario utilizando el tipo UserManager (userManager.CreateAsync).
Autentíquese a los usuarios mediante el tipo SignInManager. Puede usar
signInManager.SignInAsync
para iniciar sesión directamente osignInManager.PasswordSignInAsync
para confirmar que la contraseña del usuario es correcta y, a continuación, iniciar sesión.Identifique a un usuario en función de la información almacenada en una cookie (que es leída por el middleware de ASP.NET Core Identity) para que las solicitudes posteriores de un navegador incluyan la identidad y las reclamaciones del usuario que ha iniciado sesión.
ASP.NET Core Identity también admite la autenticación en dos fases.
En escenarios de autenticación que usan un almacén de datos de usuario local y que conservan la identidad entre solicitudes mediante cookies (como es habitual para las aplicaciones web de MVC), ASP.NET Core Identity es una solución recomendada.
Autenticación con proveedores externos
ASP.NET Core también admite el uso de proveedores de autenticación externos para permitir que los usuarios inicien sesión a través de flujos de OAuth 2.0 . Esto significa que los usuarios pueden iniciar sesión con procesos de autenticación existentes de proveedores como Microsoft, Google, Facebook o Twitter y asociar esas identidades a una identidad de ASP.NET Core en la aplicación.
Para usar la autenticación externa, además de incluir el middleware de autenticación como se mencionó anteriormente utilizando el método app.UseAuthentication()
, también tiene que registrar el proveedor externo en Program.cs como se muestra en el ejemplo siguiente.
//...
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication()
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = builder.Configuration["Authentication:Microsoft:ClientId"];
microsoftOptions.ClientSecret = builder.Configuration["Authentication:Microsoft:ClientSecret"];
})
.AddGoogle(googleOptions => { ... })
.AddTwitter(twitterOptions => { ... })
.AddFacebook(facebookOptions => { ... });
//...
Los proveedores de autenticación externos populares y sus paquetes NuGet asociados se muestran en la tabla siguiente:
proveedor | Paquete |
---|---|
Microsoft | Microsoft.AspNetCore.Authentication.MicrosoftAccount |
Microsoft.AspNetCore.Authentication.Google | |
Microsoft.AspNetCore.Authentication.Facebook | |
Microsoft.AspNetCore.Authentication.Twitter |
En todos los casos, debe completar un procedimiento de registro de aplicación dependiente del proveedor y que normalmente implica:
- Obtención de un identificador de aplicación cliente.
- Obtener un secreto de aplicación cliente.
- Configuración de la URL de redireccionamiento que está controlada por el middleware de autorización y el proveedor registrado.
- Opcionalmente, configurar una dirección URL de cierre de sesión para controlar correctamente el cierre de sesión en un escenario de inicio de sesión único (SSO).
Para obtener más información sobre cómo configurar la aplicación para un proveedor externo, consulte autenticación del proveedor externo en la documentación de ASP.NET Core).
Sugerencia
Todos los detalles se controlan mediante el middleware de autorización y los servicios mencionados anteriormente. Por lo tanto, solo tiene que elegir la opción de autenticación cuenta de usuario individual al crear el proyecto de aplicación web ASP.NET Core en Visual Studio, como se muestra en la figura 9-3, además de registrar los proveedores de autenticación mencionados anteriormente.
Figura 9-3. Al crear un proyecto de aplicación web en Visual Studio 2019, seleccione la opción Cuentas de usuario individuales para usar la autenticación externa.
Además de los proveedores de autenticación externos enumerados anteriormente, hay paquetes de terceros disponibles que proporcionan middleware para usar muchos más proveedores de autenticación externos. Para obtener una lista, consulte el repositorio AspNet.Security.OAuth.Providers en GitHub.
También puede crear su propio middleware de autenticación externa para resolver algunas necesidades especiales.
Autenticación con tokens de portador
La autenticación con ASP.NET Core Identity (o Identity más proveedores de autenticación externos) funciona bien para muchos escenarios de aplicaciones web en los que el almacenamiento de información del usuario en una cookie es adecuado. Sin embargo, en otros escenarios, las cookies no son un medio natural de conservar y transmitir datos.
Por ejemplo, en una API web de ASP.NET Core que expone puntos de conexión RESTful a los que pueden acceder aplicaciones de página única (SPA), clientes nativos o incluso otras API web, se prefiere usar la autenticación de token de portador en cambio. Estos tipos de aplicaciones no funcionan con cookies, pero pueden recuperar fácilmente un token de portador e incluirlo en el encabezado de autorización de las solicitudes posteriores. Para habilitar la autenticación de tokens, ASP.NET Core admite varias opciones para usar OAuth 2.0 y OpenID Connect.
Autenticación con un proveedor de identidades de OpenID Connect o OAuth 2.0
Si la información del usuario se almacena en Azure Active Directory u otra solución de identidad que admita OpenID Connect o OAuth 2.0, puede usar el paquete Microsoft.AspNetCore.Authentication.OpenIdConnect para autenticarse mediante el flujo de trabajo de OpenID Connect. Por ejemplo, para autenticarse en el microservicio Identity.Api en eShopOnContainers, una aplicación web ASP.NET Core puede usar middleware desde ese paquete, como se muestra en el ejemplo simplificado siguiente en Program.cs:
// Program.cs
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
var callBackUrl = builder.Configuration.GetValue<string>("CallBackUrl");
var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60);
// Add Authentication services
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime))
.AddOpenIdConnect(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = identityUrl.ToString();
options.SignedOutRedirectUri = callBackUrl.ToString();
options.ClientId = useLoadTest ? "mvctest" : "mvc";
options.ClientSecret = "secret";
options.ResponseType = useLoadTest ? "code id_token token" : "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.RequireHttpsMetadata = false;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("orders");
options.Scope.Add("basket");
options.Scope.Add("marketing");
options.Scope.Add("locations");
options.Scope.Add("webshoppingagg");
options.Scope.Add("orders.signalrhub");
});
// Build the app
//…
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
//...
});
Cuando se usa este flujo de trabajo, no se necesita el middleware de ASP.NET Core Identity, ya que el servicio Identity controla todo el almacenamiento de información del usuario y la autenticación.
Emisión de tokens de seguridad desde un servicio ASP.NET Core
Si prefiere emitir tokens de seguridad para usuarios locales de ASP.NET Core Identity en lugar de usar un proveedor de identidades externo, puede aprovechar algunas bibliotecas de terceros adecuadas.
IdentityServer4 y OpenIddict son proveedores de OpenID Connect que se integran fácilmente con ASP.NET Core Identity para permitirle emitir tokens de seguridad desde un servicio ASP.NET Core. La documentación de IdentityServer4 tiene instrucciones detalladas para usar la biblioteca. Sin embargo, los pasos básicos para usar IdentityServer4 para emitir tokens son los siguientes.
Para configurar IdentityServer4 en Program.cs , realice una llamada al generador. Services.AddIdentityServer.
Llamas al método app.UseIdentityServer en Program.cs para agregar IdentityServer4 a la canalización de procesamiento de solicitudes HTTP de la aplicación. Esto permite a la biblioteca atender solicitudes a los puntos de conexión de OpenID Connect y OAuth2, como /connect/token.
Para configurar el servidor de identidades, establezca los datos siguientes:
Credenciales que se van a usar para firmar.
Los recursos de identidad y API a los que los usuarios pueden solicitar acceso:
Los recursos de API representan datos protegidos o funcionalidad a los que un usuario puede acceder con un token de acceso. Un ejemplo de un recurso de API sería una API web (o un conjunto de API) que requiere autorización.
Los recursos de identidad representan información (declaraciones) que se proporciona a un cliente para identificar a un usuario. Las afirmaciones pueden incluir el nombre de usuario, la dirección de correo electrónico, etcétera.
Los clientes que se conectarán para solicitar tokens.
Mecanismo de almacenamiento para la información del usuario, como ASP.NET Core Identity o una alternativa.
Al especificar clientes y recursos para su uso por IdentityServer4, puede pasar una IEnumerable<T> colección del tipo adecuado a los métodos que utilizan almacenes en memoria de clientes o recursos. O bien, para escenarios más complejos, puede proporcionar tipos de cliente o de proveedor de recursos mediante inyección de dependencias.
Una configuración de ejemplo para IdentityServer4 para usar los clientes y recursos en memoria proporcionados por un tipo IClientStore personalizado podría ser similar al ejemplo siguiente:
// Program.cs
builder.Services.AddSingleton<IClientStore, CustomClientStore>();
builder.Services.AddIdentityServer()
.AddSigningCredential("CN=sts")
.AddInMemoryApiResources(MyApiResourceProvider.GetAllResources())
.AddAspNetIdentity<ApplicationUser>();
//...
Consumir tokens de seguridad
La autenticación en un punto de conexión de OpenID Connect o la emisión de sus propios tokens de seguridad cubre algunos escenarios. ¿Pero qué ocurre con un servicio que simplemente necesita limitar el acceso a los usuarios que tienen tokens de seguridad válidos proporcionados por un servicio diferente?
En ese escenario, el middleware de autenticación que controla los tokens JWT está disponible en el paquete Microsoft.AspNetCore.Authentication.JwtBearer . JWT significa "JSON Web Token" y es un formato de token de seguridad común (definido por RFC 7519) para comunicar notificaciones de seguridad. Un ejemplo simplificado de cómo usar middleware para consumir estos tokens podría parecerse a este fragmento de código, tomado del microservicio Ordering.Api de eShopOnContainers.
// Program.cs
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
// Add Authentication services
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = identityUrl;
options.RequireHttpsMetadata = false;
options.Audience = "orders";
});
// Build the app
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
//...
});
Los parámetros de este uso son:
Audience
representa el receptor del token entrante o el recurso al que el token concede acceso. Si el valor especificado en este parámetro no coincide con el parámetro del token, se rechazará el token.Authority
es la dirección del servidor de autenticación emisora de tokens. El middleware de autenticación de portador JWT usa este URI para obtener la clave pública que se puede usar para validar la firma del token. El middleware también confirma que eliss
parámetro del token coincide con este URI.
Otro parámetro, RequireHttpsMetadata
, es útil para realizar pruebas; establezca este parámetro en false para que pueda probar en entornos en los que no tenga certificados. En las implementaciones reales, los tokens de portador JWT siempre deben pasarse solo a través de HTTPS.
Con este middleware implementado, los tokens JWT se extraen automáticamente de los encabezados de autorización. A continuación, se deserializan, validan (mediante los valores de los Audience
parámetros y Authority
) y se almacenan como información de usuario a la que se hace referencia más adelante mediante las acciones de MVC o los filtros de autorización.
El middleware de autenticación de portador JWT también puede admitir escenarios más avanzados, como el uso de un certificado local para validar un token si la entidad no está disponible. En este escenario, puede especificar un TokenValidationParameters
objeto en el JwtBearerOptions
objeto .
Recursos adicionales
Uso compartido de cookies entre aplicaciones
https://learn.microsoft.com/aspnet/core/security/cookie-sharingIntroducción a la identidad
https://learn.microsoft.com/aspnet/core/security/authentication/identityAutenticación en dos fases con SMS
https://learn.microsoft.com/aspnet/core/security/authentication/2faHabilitación de la autenticación mediante Facebook, Google y otros proveedores externos
https://learn.microsoft.com/aspnet/core/security/authentication/social/Michell Anicas. Introducción a OAuth 2
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2AspNet.Security.OAuth.Providers (repositorio de GitHub para proveedores de OAuth de ASP.NET)
https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/tree/dev/srcIdentityServer4. Documentación oficial
https://identityserver4.readthedocs.io/en/latest/