Introducción a ASP.NET Core Identity

06 Jun 2024 20 min (0) Comentarios

Los que me seguís en este canal sabréis que siempre he sido muy crítico con microsoft por el tema de auth en C#  y es que auth es muy complejo, difícil de administrar y un dolor de muelas de mantener. 

Pero, pese a que todo eso sigue siendo verdad en .NET 8 introdujeron un cambio que mitiga gran parte de este problema. 

 

 

 

1 - Identity API en ASP.NET CORE

 

Desde .NET 8 cada vez que creamos un nuevo proyecto con visual studio podemos marcar una casilla para especificar que queremos utilizar identity:

 

identity .net

Lo que esta casilla hace por detrás es darnos una abstracción para administrar los usuarios de nuestra aplicación y si lo deseamos podemos incluir otros proveedores de Auth o incluso doble factor de autenticación.

 

Cuando marcamos la casilla, lo que la plantilla por defecto nos va a dar el modelo de datos de IdentityUser y IdentityRole los cuales pueden ser guardados en una base de datos a través de entity framework y clases para facilitar el registro, administración, etc. de estos usuarios. 

 

Pero esto no es todo, en el front end nos genera una interfaz y en el backend, junto al modelo de datos podemos incluir una API, estas funcionalidades las veremos en un momento.

 

 

2 - Por qué necesitamos identity API?

 

Mi opinión personal es que esta funcionalidad llega 20 años tarde, pero mejor tarde que nunca, ¿no?

 

Pero vamos a los motivos reales. De siempre cuando trabajamos con C# trabajar con usuarios, permisos, etc ha sido un dolor, lo más sencillo y lo que yo hago en mi web es tener un servicio de terceros donde todo se puede administrar en su propia API o interfaz. 

 

Los que lleváis más tiempo programando recordareis que microsoft tenía su versión open source de identity llamada IdentityServer la cual fue vendida a duende software, y lo que hacían las empresas que querían administrar todo en sus servidores era un fork de ese servicio y cambiar el código. Personalmente he trabajado en varias empresas que hacían esto, y doy gracias por no tener que hacerlo más. 

 

Con la llegada de esta librería Microsoft nos facilita el uso de usuarios en la propia aplicación en vez de tener que utilizar una diferente, permitiendo a ASP.NET Core tener una funcionalidad muy importante que otros frameworks web como Rails o Laravel ya traen por defecto. Gracias a esta librería podemos, ahora sí, utilizar un único backend escrito en .NET y un front end escrito en cualquier lenguaje, si queremos separar el back del front por supuesto.

 

front calling back

Y si queremos tenerlo todo en una app como puede ser MVC nos permite tenerlo todo en una única app sin que sea muy complejo.

 

O incluso si queremos tener un servicio externo donde validamos a los usuarios también es posible.

validar usuarios

La idea de la api de identidad de .NET es permitir al Front-end y al back-end hablar entre sí,  y como digo, la idea principal es la simplicidad de cara al usuario o empresa que está empezando, y quiero remarcar empezando, porque, por motivos que veremos más adelante no me parece una funcionalidad completa al 100% para empresas con cientos o miles de clientes.

 

Aún así, para muchos escenarios nos sobra, un ejemplo es este blog, yo implemente a los usuarios antes de que existiera esta funcionalidad, pero si lo tuviera que hacer ahora lo implementaría así. 

 

 

3 - Cómo funciona Identity en .NET

 

La nueva librería funciona de una forma muy sencilla y con muy poco código, por defecto el proyecto nos viene con un DBcontext de Entity Framework el cual implementa  IdentityDbContext:

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Esta configuración es la que nos permite tener usuarios, roles, etc.

 

Ahora en nuestra clase program es donde vamos a incluir la mayoría del código.

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
	.AddEntityFrameworkStores<ApplicationDbContext>(

 

NOTA: la versión que viene en la plantilla viene con `options => options.SignIn.RequireConfirmedAccount = true` que es para validar el email, como este escenario es de prueba y local no lo queremos, pero en producción dejalo habilitado. 

 

Además, podemos utilizar un objeto diferente a IdentityUser si vamos a incluir modificaciones adicionales a objeto.

 

Por supuesto que no se pasa por algo que necesitamos tanto incluir AddAuthorization al contenedor de dependencias.

Como el middleware de authorization. 

builder.Services.AddAuthorization();
app.UseAuthorization();

 

NOTA: Si estás haciendo el proyecto de 0 y es un proyecto nuevo, vas a tener que ejecutar las migraciones, que no se te olvide.

 

 

3.1 - La interfaz Identity en .NET

 

Al marcar la casilla de identity se nos va a crear un front end este front end es muy básico pero nos sirve para lo que buscamos, contiene una forma de crear cuentas, hacer log in, cerrar sesión, etc, lo básico:

identity ui net core

Y no tiene mucho más misterio,  al iniciar sesión se incluye una cookie con tu Bearer token en el navegador la cual se usa para la identidad. 

 

Hay que tener una serie de consideraciones con esta interfaz, la primera es que nos viene por defecto y está ubicada en lo que se conoce como un Area en ASP.NET Core y pese a que se puede cambiar, personalmente no lo recomiendo.

 

Todo el código que tiene que ver con esta funcionalidad está en la librería que nos da microsoft y para hacernos una idea son más de 30 páginas diferentes, que incluyen tanto el registro, al iniciar sesión o reiniciar la contraseña, que puedes pensar que son páginas básicas, pero a esas hay que sumarle todo lo de administración de usuarios, doble factor, logins externos, errores, etc. 

 

Al final son un buen número de páginas que en mi opinión, si usas esta funcionalidad es porque tu empresa no está al punto de querer/tener que administrar manualmente toda la funcionalidad. Si por ejemplo estás captando clientes, el cómo se haga el registro te puede dar un poco igual al principio, pero más adelante vas a tener que poner una interfaz más vistosa y sería lo que implica que tengas que construir la interfaz. 

 

En un blog, en mi opinión está bien y aceptable, aunque no ideal ya que el estilo de la interfaz no se puede cambiar.

 

 

3.2 - API de identity en .NET

 

Al margen de si la interfaz de usuario que viene por defecto es usable o no, puede ser que tengas la UI y la API separadas, estando la API en una zona segura de tu arquitectura donde los usuarios no pueden entrar por lo que vas a necesitar usar la API.

 

Por defecto en el tipo de proyecto que hemos elegido la API no nos viene configurada, así que tenemos que hacerlo, para ello incluimos lo siguiente: 

app.MapGroup("/identity").MapIdentityApi<IdentityUser>();

 

Con este código, lo que hacemos es crear una serie de endpoints que se mapean dentro de /identity y pese a que ya están accesibles, voy a instalar y configurar swagger para poder verlos en el navegador: 

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(ctx => ctx.AddSecurityDefinition("token", new OpenApiSecurityScheme
{
    Type = SecuritySchemeType.Http,
    In = ParameterLocation.Header,
    Name = HeaderNames.Authorization,
    Scheme = "Bearer"
}));


  app.UseSwagger();
  app.UseSwaggerUI();

 

Y si ahora probamos vemos que podemos acceder al swagger:

identity en swagger

Lo que nos queda ahora es hacer el login. Para ello vamos al campo de login y realizamos la llamada, vemos que funciona porque nos devuelve un 200, pero no vemos nada, eso es porque ha respondido el token en el header de la respuesta

 

ejecución identity api

Para evitar esto lo que tenemos que hacer es incluir en el AddAuthentication que utilice el bearer token, pero claro, dónde está ese método? Está dentro de AddDefaultIdentity que es parte de la librería de identity, por lo que no lo podemos cambiar de una forma sencilla. Lo que vamos a hacer es copiar el contenido de ese método y así poder modificarlo

//builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
//    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddAuthentication(o =>
{
    o.DefaultScheme = IdentityConstants.ApplicationScheme;
    o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
    .AddBearerToken(IdentityConstants.BearerScheme)

      .AddIdentityCookies(o => { })
      ;

builder.Services.AddIdentityCore<IdentityUser>(options =>
{
    options.Stores.MaxLengthForKeys = 128;
    options.SignIn.RequireConfirmedAccount = false;
})
    .AddDefaultUI()
    .AddDefaultTokenProviders()
    .AddEntityFrameworkStores<ApplicationDbContext>();

 

Las dos primeras líneas son las que teníamos antes, las cuales he dejado comentadas. 

El resto del código es lo que estaba dentro, pero con la pequeña modificacion del BearerToken. 

bearer token identity api .net

Y podemos utilizarlo para realizar llamadas a la API. 

 

Pese a que la implementación es sencilla, la API en sí tiene un problema, y es que igual que la interfaz, los endpoints no se pueden modificar y estamos a merced de la implementación de la librería sobre su funcionamiento. 

 

Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café