Hace unas semanas escribí una serie de artículos donde compartí paso a paso como dar los primeros pasos con Azure AD B2C y cómo configurar el servicio de forma correcta.

En este artículo veremos como realizar la integración de Azure AD B2C con aplicaciones Web MVC .Net 5 de forma fácil y rápida.

IMPORTANTE: trabajaremos sobre la base construida en los artículos anteriores, con lo cual es recomendable tener claros los conceptos y pasos allí detallados.

Antes de Comenzar

En este tutorial vamos a utilizar .Net 5 como marco o framework de desarrollo, con lo cual es un requisito excluyente tener instalado .Net 5 SDK. Si aún no lo tienes, lo puedes descargar aquí, también encontrarás un instructivo paso a paso en caso de que tengas dudas.

Por otro lado, vamos a utilizar Visual Studio 2019 Community Edition, sin embargo este no es un requerimiento excluyente ya que podemos utilizar cualquier editor de texto o ambiente de desarrollo como Visual Studio Code o Notepad++. Puedes descargar Visual Studio 2019 aquí.

Contexto

En la actualidad, casi cualquier aplicación requiere que ciertas partes o componentes estén restringidas a usuarios autenticados de la aplicación.

Habitualmente la autenticación se realiza presentando al usuario un formulario de Inicio de sesión donde debe ingresar el nombre de usuario o email y una contraseña.

Es aquí donde entra Azure AD B2C y los flujos de usuario.

Requerimiento

Tenemos una aplicación Web MVC .Net 5 la cual queremos integrar con nuestro Azure AD B2C. Esta aplicación todavía no implementa ningún tipo de autenticación.

La idea principal es que no sólo aprendamos a integrar Azure AD B2C si no que además veamos los requerimientos mínimos para comenzar a utilizar Autenticación.

Microsoft Identity Web

Microsoft ha estado mejorando y simplificando la forma en la que se integran aplicaciones web con Azure AD, no solo soportando estándares como OAuth2 y OpenID Connect, sino también reduciendo la cantidad de código necesario para implementar la solución.

Para nuestra integración utilizaremos las librerías Microsoft.Identity.Web y Microsoft.Identity.Web.UI. Estas librerías están construidas sobre la Biblioteca de Autehticación de Microsoft o MSAL.

  • Microsoft.Identity.Web
    Esta librería proporciona los mecanismos necesarios para interactuar con Azure AD de una forma simple, segura y estándar. Por ejemplo, los manejadores para las URL de redirección para el inicio de sesión y el cierre de sesión.
  • Microsoft.Identity.Web.UI
    Esta librería proporsiona los componentes visuales (controladores y vistas) necesarias para la integración, como pantallas de consentimiento, cierre de sessión, etc.

Paso 1: Solución, proyecto y librerías

Comenzaremos creando una solución y un proyecto Web MVC. Luego instalaremos las dos librerías mencionadas en la sección anterior y para validar que todo esté funcionando correctamente compilaremos y ejecutaremos la solución.

# Crear solución y projecto MVC
dotnet new sln --name AzureAdB2C
dotnet new mvc --name AzureAdB2C.MVC --output AzureAdB2C.MVC
dotnet sln add .\AzureAdB2C.MVC\AzureAdB2C.MVC.csproj

# Instalar las librerías necesarias
dotnet add .\AzureAdB2C.MVC\AzureAdB2C.MVC.csproj package Microsoft.Identity.Web
dotnet add .\AzureAdB2C.MVC\AzureAdB2C.MVC.csproj package Microsoft.Identity.Web.UI

# Restaurar y compilar
dotnet restore
dotnet build

# Ejecutar
dotnet run --project .\AzureAdB2C.MVC\AzureAdB2C.MVC.csproj

Deberíamos ver algo similar al siguiente resultado desde la consola, donde se proporcionará la URL local para poder acceder al sitio web y corroborar que esta funcionando.

Dotnet run desde la línea de comandos
Dotnet run desde la línea de comandos
Home aplicación web MVC
Home aplicación web MVC

Paso 2: Configuración de servicios y pipeline

Vamos a configurar los servicios necesarios para la integración con Azure AD B2C. Además configuraremos el pipeline para utilizar Autenticación.

Para este realizaremos los cambios detallados a continuación en la clase Startup.cs del proyecto AzureAdB2C.MVC.

Como paso preliminar agregaremos los siguientes usings a la clase Startup.cs:

using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;

ConfigureServices

Por un lado tenemos que configurar los servicios necesarios relacionados a la interfaz de usuario, como por ejemplo las vistas de consentimiento y cierre de sesión.

Uno de los cambios interesantes en la nueva librería MSAL es que incluye todos los controladores y vistas necesarias en forma predeterminada. Esto quiere decir que si no tenemos requerimientos especiales, no necesitamos crear ningún controlador ni vista adicional.

Necesitamos incluir los metodos de extension AddMicrosoftIdentityUI() para la parte de la interfaz de usuario y AddMicrosoftIdentityWebAppAuthentication() para la integración con Azure AD B2C.

Además incluiremos los servicios necesarios para trabajar con Razor Pages, ya que son requeridos por AddMicrosoftIdentityUI()

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews()
        .AddMicrosoftIdentityUI();

    services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C");

    services.AddRazorPages();
}

El método AddMicrosoftIdentityWebAppAuthentication() requiere como parámetro inicial el objeto de configuración IConfiguration y como segundo parámetro el nombre de la sección de configuración a utilizar, en este caso "AzureAdB2C". Agregaremos esta sección de configuración mas adelante en archivo appsettings.json.

Configure

El único requisito a nivel de pipeline, es incluir el middleware de autenticación con el método UseAuthentication(). Debido a que estamos trabajando con el pipeline, es muy importante respetar el orden en el que llamamos al método.

Tiene que ser después de UseRouting() y antes de UseAuthorization().

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

Por último, incluiremos el pipeline para utilizar Razor Pages.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapRazorPages();
});

Paso 3: Vistas para inicio y cierre de sesión

Ya que partimos de una aplicación Web MVC base, el sitio todavía no ofrece las acciones para inicio y cierre de sesión correspondientes. Esta es una tarea que tendremos que hacer nosotros.:

La implementación consiste en

  • Agregar una vista parcial incluyendo las acciones para inicio y cierre de sesión, habitualmente llamada _LoginPartial.cshtml.
  • Modificar la vista parcial _Layout.cshtml para incluir la vista del punto anterior.

_LoginPartial.cshtml

Esta vista se encargara de mostrar la acción para inicio de sesión en el caso de que el usuario no haya iniciado sesión aún, o mostrar el nombre del usuario junto con la acción de cerrar sesión en caso contrario.

@using Microsoft.Identity.Web
@if (User.Identity.IsAuthenticated)
{
    <ul class="nav navbar-nav navbar-right">
        <li class="navbar-text">Hello @User.GetDisplayName()!</li>
        <li><a asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a></li>
    </ul>
}
else
{
    <ul class="nav navbar-nav navbar-right">
        <li><a asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a></li>
    </ul>
}

Algo destacable son las acciones para inicio de sesión (Sign in) y cierre de sesión (Sign out). Ambas utilizan el controlador Account dentro del área MicrosoftIdentity.

Este controlador forma parte de la librería Microsoft.Identity.Web.UI. Este uno de los mejores cambios que esta librería nos ofrece, ya que nos evita tener que crear controladores y vistas.

_Layout.cshtml

Esta vista contiene, entre otras cosas, la cabecera (header) con la barra de navegación (navbar) o menú. Agregaremos como parte de la cabecera la vista parcial que creamos en la sección anterior.

<header>
    <nav class="navbar navbar-expand-sm ...">
        <div class="container">
            <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">AzureAdB2C.MVC</a>
            <button class="navbar-toggler">...            </button>
            <div class="navbar-collapse collapse ...">
                <ul class="navbar-nav flex-grow-1">...</ul>
                <partial name="_LoginPartial" />
            </div>
        </div>
    </nav>
</header>

Si ejecutamos la aplicación ahora veremos disponible la acción Sign in en la barra de menú sobre la parte de arriba a la derecha.

Home aplicación web MVC con Inicio de Sesión
Home aplicación web MVC con Inicio de Sesión

Paso 4: Agregar URLs de redirección en Azure AD B2C

Ya con nuestra aplicación funcionando, configuraremos la URL de redirección hacia nuestro sitio web local para el inicio de sesión y para el cierre de sesión. Como vimos anteriormente, Microsoft.Identity.Web incluye ambos manejadores.

  • El manejador de inicio de sesión responde a la URL /signin-oidc, que en nuestro ambiente de desarrollo local sería https:localhost:5001/signin-oidc.
  • El manejador de cierre de sesión responde a la URL /signout-oidc, que en nuestro ambiente de desarrollo local sería https:localhost:5001/signout-oidc.

Cuando realizamos la configuración inicial del tenant, registramos una nueva aplicación llamada Sitio Web Increíble donde agregamos una URL de redirección de prueba.

Para agregar la URL de redirección, desde el registro de aplicación Sitio Web Increíble en la sección Autenticación, tendremos la lista de URLs. Haciendo clic en Agregar un URI podremos agregar el nuestro.

Más abajo, agregaremos también la URL de cierre de sesión del canal frontal. Importante siempre guardar los cambios.

Configuración URL de retorno Azure AD B2C
Configuración URL de retorno Azure AD B2C

Paso 5: Recolectar información de Azure AD B2C

Para finalizar la integración necesitamos disponer de los siguientes datos:

  • Instancia
  • Dominio
  • Id de Cliente
  • Id del flujo de Inicio de Sesión y Registro

Instancia y Dominio

Si bien el nombre de la instancia y el nombre del dominio son diferentes, en ambas requerimos el subdominio. El subdominio lo podemos obtener desde el panel de Información General del tenant a partir del Nombre de Dominio.

Panel de información general Azure AD B2C
Panel de información general Azure AD B2C

Ya con el nombre de dominio completo, vamos a extraer la primer parte, y ese será el subdominio que usaremos para construir el nombre de la instancia. En el ejemplo anterior el nombre de dominio es linkedinazureadb2c.onmicrosoft.com, nos quedaremos con linkedinazureadb2c.

El nombre de instancia responde al siguiente formato https://{subdominio}.b2clogin.com, donde reemplazaremos {subdominio} por linkedinazureadb2c.

Estos son los valores que necesitamos:

  • Instancia: https://linkedinazureadb2c.b2clogin.com
  • Dominio: linkedinazureadb2c.onmicrosoft.com

Id de Cliente

El Id de Cliente o Client Id es el Id de registro de aplicación (Sitio Web Increíble). Y lo podemos obtener desde la lista de registros de aplicaciones bajo la columna Id de aplicación (cliente).

Registros de aplicaciones Azure AD B2C
Registros de aplicaciones Azure AD B2C

Id del flujo de Inicio de Sesión y Registro

El último dato que necesitamos es el id del flujo de usuario para inicio de sesión y registro, el cual obtendremos desde la sección de flujos de usuarios bajo la columna Nombre.

Flujos de usuario Azure AD B2C
Flujos de usuario Azure AD B2C

Paso 6: Configuración de la aplicación Web MVC

En este punto solo nos falta tomar la información que recolectamos anteriormente y configurar la aplicación Web MVC para que se integre correctamente con Azure AD B2C.

En el archivo de configuración appsettings.json agregaremos una nueva sección llamada “AzureAdB2C” con las cuatro piezas de información del paso anterior.

"AzureAdB2C": {
  "Instance": "https://linkedinazureadb2c.b2clogin.com",
  "ClientId": "f4ad0000-0000-0000-0000-000000004aec",
  "Domain": "linkedinazureadb2c.onmicrosoft.com",
  "SignUpSignInPolicyId": "B2C_1_InicioSesionConRegistro"
}

Paso 7: Pruebas

Si realizamos todos los pasos correctamente, al clicar en la acción Sign In seremos redireccionados a Azure AD B2C para iniciar sesión. Una vez el usuario ha sido autenticado exitosamente, veremos el nombre del usuario junto con la acción Sign Out.

Home aplicación web MVC con Cierre de Sesión
Home aplicación web MVC con Cierre de Sesión

Si ahora clicamos en la acción Sign out seremos redireccionados primero a Azure AD B2C, donde limpiaran las cookies de sesión y finalmente a la página de confirmación de cierre de sesión.

Home aplicación web MVC confirmación de Cierre de Sesión
Home aplicación web MVC confirmación de Cierre de Sesión

El redireccionamiento hacia Azure AD B2C y posteriormente hacia la página de confirmación de cierre de sesión suele ser muy rápido, en términos prácticos es imperceptible.

Conclusión

En este post vimos cómo integrar Azure AD B2C con aplicaciones Web MVC .Net 5 en forma fácil y rápida, incluyendo inicio y cierre de sesión.

Podrás encontrar el código completo en mi GitHub.