Habilitación de la autenticación en su propia API web mediante Azure Active Directory B2C

Para autorizar el acceso a una API web, puede atender solo las solicitudes que incluyan un token de acceso válido que Azure Active Directory B2C (Azure AD B2C) emita. En este artículo se muestra cómo habilitar la autorización de Azure AD B2C para la API web. Después de completar los pasos de este artículo, solo los usuarios que obtengan un token de acceso válido estarán autorizados para llamar a los puntos de conexión de la API web.

Requisitos previos

Antes de empezar, lea uno de los siguientes artículos, en los que se explica cómo configurar la autenticación para aplicaciones que llaman a las API web. A continuación, siga los pasos descritos en este artículo para reemplazar la API web de ejemplo por su propia API web.

Información general

La autenticación basada en tokens garantiza que las solicitudes a una API web van acompañadas de un token de acceso válido.

La aplicación completa los siguientes pasos:

  1. Para autenticar a los usuarios con Azure AD B2C.

  2. Adquiere un token de acceso con los permisos necesarios (ámbitos) para el punto de conexión de API web.

  3. Pasa el token de acceso como token de portador en el encabezado de autorización de la solicitud HTTP con este formato:

    Authorization: Bearer <access token>
    

La API web completa los siguientes pasos:

  1. Lee el token de portador del encabezado de autorización en la solicitud HTTP.

  2. Valida el token.

  3. Valida los permisos (ámbitos) en el token.

  4. Lee las notificaciones codificadas en el token (opcional).

  5. Responde a la solicitud HTTP.

Introducción al registro de aplicaciones

Para que la aplicación pueda iniciar sesión con Azure AD B2C y llame a una API web, debe registrar dos aplicaciones en el directorio de Azure AD B2C.

  • El registro de la aplicación web, móvil o SPA permite que la aplicación inicie sesión con Azure AD B2C. El proceso de registro de la aplicación genera un identificador de aplicación, también conocido como id. de cliente, que permite identificar de forma exclusiva la aplicación (por ejemplo, id. de aplicación: 1).

  • El registro de API web permite que su aplicación llame a una API web protegida. El registro expone los permisos de la API web (ámbitos). El proceso de registro de la aplicación genera un identificador de aplicación, que identifica de forma exclusiva la API web (por ejemplo, id. de aplicación: 2). Conceda a la aplicación (id. de aplicación: 1) permisos para los ámbitos de la API web (id. de aplicación: 2).

Los registros y la arquitectura de la aplicación se describen en el diagrama siguiente:

Diagram of the application registrations and the application architecture for an app with web API.

Preparación del entorno de desarrollo

En las secciones siguientes, se crea un proyecto de API web. Seleccione el lenguaje de programación, ASP.NET Core o Node.js. Asegúrese de que su equipo ejecuta cualquiera de los siguientes programas de software:

Paso 1: Creación de una API web protegida

Cree un proyecto de API web. En primer lugar, seleccione el lenguaje de programación que desea usar, ASP.NET Core o Node.js.

Use el comando dotnet new. El comando dotnet new crea una carpeta denominada TodoList con los recursos del proyecto de API web. Abra el directorio y, a continuación, abra Visual Studio Code.

dotnet new webapi -o TodoList
cd TodoList
code . 

Cuando se le pida que "agregue los recursos necesarios al proyecto", seleccione .

Paso 2: Instalación de las dependencias.

Agregue la biblioteca de autenticación al proyecto de la API web. La biblioteca de autenticación analiza el encabezado de autenticación HTTP, valida el token y extrae las notificaciones. Para obtener más información, revise la documentación de la biblioteca.

Para agregar la biblioteca de autenticación, instale el paquete mediante la ejecución del siguiente comando:

dotnet add package Microsoft.Identity.Web

Paso 3: Inicio de la biblioteca de autenticación

Agregue el código necesario para iniciar la biblioteca de autenticación.

Abra el archivo Startup.cs y, a continuación, agregue las siguientes declaraciones using al principio de la clase:

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

Busque la función ConfigureServices(IServiceCollection services). A continuación, antes de la línea de código services.AddControllers();, agregue el siguiente fragmento de código:

public void ConfigureServices(IServiceCollection services)
{
    // Adds Microsoft Identity platform (Azure AD B2C) support to protect this Api
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(options =>
    {
        Configuration.Bind("AzureAdB2C", options);

        options.TokenValidationParameters.NameClaimType = "name";
    },
    options => { Configuration.Bind("AzureAdB2C", options); });
    // End of the Microsoft Identity platform block    

    services.AddControllers();
}

Busque la función Configure. A continuación, inmediatamente después de la línea de código app.UseRouting();, agregue el siguiente fragmento de código:

app.UseAuthentication();

Después del cambio, el código debe ser parecido al siguiente fragmento de código:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();
    
    // Add the following line 
    app.UseAuthentication();
    // End of the block you add
    
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Paso 4: Adición de los puntos de conexión

Agregue dos puntos de conexión a la API web:

  • Punto de conexión /public anónimo. Este punto de conexión devuelve la fecha y hora actuales. Úselo para depurar la API web con llamadas anónimas.
  • Punto de conexión /hello protegido. Este punto de conexión devuelve el valor de la notificación name dentro del token de acceso.

Para agregar el punto de conexión anónimo:

En la carpeta /Controllers, agregue un archivo PublicController.cs y, a continuación, agréguelo al fragmento de código siguiente:

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace TodoList.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class PublicController : ControllerBase
    {
        private readonly ILogger<PublicController> _logger;

        public PublicController(ILogger<PublicController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public ActionResult Get()
        {
            return Ok( new {date = DateTime.UtcNow.ToString()});
        }
    }
}

Para agregar el punto de conexión protegido:

En la carpeta /Controllers, agregue un archivo HelloController.cs y, a continuación, agréguelo al código siguiente:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Web.Resource;

namespace TodoList.Controllers
{
    [Authorize]
    [RequiredScope("tasks.read")]
    [ApiController]
    [Route("[controller]")]
    public class HelloController : ControllerBase
    {

        private readonly ILogger<HelloController> _logger;
        private readonly IHttpContextAccessor _contextAccessor;

        public HelloController(ILogger<HelloController> logger, IHttpContextAccessor contextAccessor)
        {
            _logger = logger;
            _contextAccessor = contextAccessor;
        }

        [HttpGet]
        public ActionResult Get()
        {
            return Ok( new { name = User.Identity.Name});
        }
    }
}

El controlador HelloController está decorado con AuthorizeAttribute, que limita el acceso solo a los usuarios autenticados.

El controlador también está decorado con [RequiredScope("tasks.read")]. El elemento RequiredScopeAttribute comprueba que se llama a la API web con los ámbitos adecuados, tasks.read.

Paso 5: Configuración del servidor web

En un entorno de desarrollo, establezca la API web para que escuche en el número de puerto de solicitudes HTTP o HTTPS entrantes. En este ejemplo, use el puerto HTTP 6000 y el puerto HTTPS 6001. El URI base de la API web será http://localhost:6000 para HTTP y https://localhost:6001 para HTTPS.

Agregue el fragmento de código JSON siguiente al archivo appsettings.json.

"Kestrel": {
    "EndPoints": {
      "Http": {
        "Url": "http://localhost:6000"
      },
      "Https": {
         "Url": "https://localhost:6001"   
        }
    }
  }

Paso 6: Configuración de la API web

Agregue configuraciones a un archivo de configuración. El archivo contiene información sobre el proveedor de identidades de Azure AD B2C. La aplicación de API web usa esta información para validar el token de acceso que la aplicación web pasa como token de portador.

En la carpeta raíz del proyecto, abra el archivo appsettings.json y, a continuación, agregue la siguiente configuración:

{
  "AzureAdB2C": {
    "Instance": "https://contoso.b2clogin.com",
    "Domain": "contoso.onmicrosoft.com",
    "ClientId": "<web-api-app-application-id>",
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },
  // More settings here
}

En el archivo appsettings.json, actualice las propiedades siguientes:

Sección Key Valor
AzureAdB2C Instancia Primera parte del nombre de inquilino de Azure AD B2C (por ejemplo, https://contoso.b2clogin.com).
AzureAdB2C Domain Nombre de inquilino completo de Azure AD B2C (por ejemplo, contoso.onmicrosoft.com).
AzureAdB2C ClientId Id. de aplicación de la API web. En el diagrama anterior, es la aplicación con id. de aplicación: 2. Para obtener información sobre cómo obtener el identificador de registro de la aplicación de API web, consulte Requisitos previos.
AzureAdB2C SignUpSignInPolicyId Flujos de usuario o directiva personalizada. Para obtener información sobre cómo obtener el flujo de usuario o la directiva, consulte Requisitos previos.

Paso 7: Ejecución y prueba de la API web

Por último, ejecute la API web con la configuración del entorno de Azure AD B2C.

En el shell de comandos, ejecute el siguiente comando para iniciar la aplicación web:

 dotnet run

Debería ver la siguiente salida, que significa que la aplicación está en funcionamiento y lista para recibir solicitudes.

Now listening on: http://localhost:6000

Para detener el programa, en el shell de comandos, seleccione Ctrl+C. Puede volver a ejecutar la aplicación mediante el comando node app.js.

Sugerencia

Como alternativa, para ejecutar el comando dotnet run, puede usar el depurador de Visual Studio Code. El depurador integrado de Visual Studio Code ayuda a acelerar el bucle de edición, compilación y depuración.

Abra un explorador y vaya a http://localhost:6000/public. En la ventana del explorador, debería ver el texto siguiente, junto con la fecha y hora actuales.

Paso 8: Llamada a la API web desde la aplicación

Intente llamar al punto de conexión de API web protegido sin un token de acceso. Abra un explorador y vaya a http://localhost:6000/hello. La API devolverá un mensaje de error HTTP no autorizado, que confirmará que la API web está protegida con un token de portador.

Siga configurando la aplicación para llamar a la API web. Para obtener instrucciones, consulte la sección Requisitos previos.

Vea este vídeo para obtener información sobre algunos procedimientos recomendados al integrar Azure AD B2C con una API.

Pasos siguientes

Obtenga el ejemplo completo en GitHub: