Uno de los requerimientos más comunes cuándo utilizamos Azure AD B2C es que sólo usuarios autenticados de nuestro tenant puedan acceder a nuestras APIs.

En este artículo veremos como configurar Azure AD B2C y como integrar una Web API .Net 5 para aceptar peticiones de usuarios autenticados.

IMPORTANTE: para poder implementar los pasos aquí mencionados es necesario contar con una configuración básica en Azure AD B2C. Podrás encontrarlos en el siguiente paso a paso.

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

Muy frecuentemente, encontramos como parte de nuestras aplicaciones componentes del tipo API REST para exponer funcionalidades específicas.

Suele ser habitual que queramos proteger dichas APIs de accesos a usuarios no autorizados o que no forman parte de nuestra aplicación.

Requerimiento

Tenemos una aplicación Web API .Net 5 la cuál queremos integrar con Azure AD B2C, de forma que solo usuarios autenticados puedan acceder.

Esta aplicación todavía no implementa ningún mecanismo de autenticación, con lo cual veremos también los pasos necesarios para configurar 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 la librería Microsoft.Identity.Web. 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.

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

Comenzaremos creando una solución y un proyecto Web API. Luego instalaremos la librería mencionada en la sección anterior y para validar que todo esté funcionando correctamente compilaremos y ejecutaremos la solución.

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

# Instalar la librería necesaria
dotnet add .\AzureAdB2C.API\AzureAdB2C.API.csproj package Microsoft.Identity.Web

# Restaurar y compilar
dotnet restore
dotnet build

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

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

Dotnet run desde la línea de comandos
Dotnet run desde la línea de comandos

Por defecto, .Net 5 incluye Swagger como mecanismo de documentación de APIs. Para acceder al mismo, usaremos la URL provista en la línea de comandos (en este caso https://localhost:5001) y agregaremos como parte de la ruta /swagger.

https://localhost:5001/swagger

Documentación con Swagger
Documentación con Swagger

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.API.

Como paso preliminar agregaremos el siguiente using a la clase Startup.cs:

using Microsoft.Identity.Web;
using Microsoft.AspNetCore.Authentication.JwtBearer;

ConfigureServices

En el método ConfigureServices configuraremos los servicios necesarios para la integración con Azure AD B2C.

Microsoft.Identity.Web incluye un método de extensión muy conveniente para configurar la integración llamado AddMicrosoftIdentityWebApi().

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(options =>
            {
                Configuration.Bind("AzureAdB2C", options);

                options.TokenValidationParameters.NameClaimType = "name";
            },
            options => { Configuration.Bind("AzureAdB2C", options); });

    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "AzureAdB2C.API", Version = "v1" });
    });
}

El método AddMicrosoftIdentityWebApi() nos permite utilizar la configuración de nuestra aplicación mediante el objeto IConfiguration indicando el nombre de la secció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();

Paso 3: Registrar la API en Azure AD B2C

Para que nuestra API pueda interactuar con Azure AD B2C es necesario generar un registro de aplicación previamente.

Para poder registrar una nueva aplicación, debemos navegar a la sección de Registros de aplicaciones situada sobre el panel de la izquierda y luego ir a Nuevo Registro.

Registro de aplicaciones
Registro de aplicaciones

En formulario de registro solo vamos a completar el campo Nombre y dejaremos el resto de los campos con sus valores por defecto. En este caso elegí como nombre “API”.

Nuevo registro de aplicación
Nuevo registro de aplicación

Ya finalizado el registro de aplicación para la API, en la sección de Información general vamos a tomar nota del Id de aplicación, ya que lo vamos a necesitar para la configuración de la API.

Id de aplicación o Client Id
Id de aplicación o Client Id

Paso 4: Exponer un ámbito o scope

Parte del requerimiento que estamos implementando implica que solo usuario autorizados puedan acceder a la API. A su vez los usuarios tienen acceso a determinadas APIs o recursos.

Esos recursos (o grupos de recursos) se representan a través de lo que se denomina ámbito o scope.

Cada API o recurso expone la lista de scopes que maneja de forma que puedan ser asignados a los usuarios en función de los roles que asignados.

A modo de ejemplo y para clarificar un poco más que es un scope, una API para gestión de Posts de un Blog, podría exponer la siguiente lista:

  • Lector: este scope habilita el acceso al los posts recomendados que un usuario puede tener en base a sus etiquetas preferidas.
  • Escritor: este scope habilita el acceso en modo edición a los posts que un usuario que ha escrito.
  • Moderador: este scope habilita la eliminación de posts que no cumplen con las reglas del blog

Exponer un ámbito o scope

Para exponer un scope vamos a ir al registro de aplicación que creamos en el paso anterior para nuestra API y luego a la sección Exponer una API. Finalmente vamos a clicar la opción Agregar un ámbito.

Exponer una API
Exponer una API

Establecer URI de Identificador

La primera vez que agregamos un scope vamos a tener que definir la URI con la cuál se identificará a todos los scopes expuestos.

URI de identitificación
URI de identitificación

Azure AD B2C sugerirá un valor aleatorio, sin embargo es recomendable asignar un valor que tenga sentido y represente la API.

Siguiendo con el ejemplo, posts es un buen nombre.

De esta forma, los scopes Lector, Escritor y Moderador se verían así:

  • https://linkedinazureb2c.onmicrosoft.com/posts/Lector
  • https://linkedinazureb2c.onmicrosoft.com/posts/Escritor
  • https://linkedinazureb2c.onmicrosoft.com/posts/Moderador

Agregar Scope

Una vez establecida la URI, continuamos con la creación del scope.

Agregar scope
Agregar scope

Paso 5: Configuración de la aplicación Web API

En este punto solo nos falta recolectar algunas piezas de información y configurar la aplicación Web API para que se integre correctamente con Azure AD B2C. La información que necesitamos es la siguiente:

  • Instancia
  • Dominio
  • Id de Cliente
  • Id de flujo de usuario

El Id de Cliente lo obtuvimos en el Paso 3 cuando registramos la API, para obtener la Instancia, Dominio y Id del flujo de Usuario te dejo esta breve sección del artículo que escribí sobre integración con aplicaciones Web MVC.

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"
}

Conclusión

En este post vimos cómo proteger una Web API con Azure AD B2C de forma que sólo usuario autenticados mediante un flujo de usuario de Azure AD B2C puedan acceder a la API.

Sin embargo, todavía no hemos podido probar la integración ya que para eso necesitamos poder autenticar un usuario.

En el próximo artículo compartiré como integrar una aplicación Web MVC con aplicaciones Web API utilizando Azure AD B2C como mecanismo de autenticación.

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