Habilitación de la autenticación en su propia API web mediante Azure Active Directory B2C
Artículo
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.
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:
Para autenticar a los usuarios con Azure AD B2C.
Adquiere un token de acceso con los permisos necesarios (ámbitos) para el punto de conexión de API web.
Pasa el token de acceso como token de portador en el encabezado de autorización de la solicitud HTTP con este formato:
HTTP
Authorization: Bearer <access token>
La API web completa los siguientes pasos:
Lee el token de portador del encabezado de autorización en la solicitud HTTP.
Valida el token.
Valida los permisos (ámbitos) en el token.
Lee las notificaciones codificadas en el token (opcional).
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:
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:
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.
CLI de .NET
dotnetnew webapi -o TodoList
cd TodoList
code .
Cuando se le pida que "agregue los recursos necesarios al proyecto", seleccione Sí.
Use Express para Node.js para crear una API web. Para crear una API web, haga lo siguiente:
Cree una carpeta con el nombre TodoList.
En la carpeta TodoList, cree un archivo denominado app.js.
En un shell de comandos, ejecute npm init -y. Este comando crea un archivo package.json predeterminado para el proyecto de Node.js.
En el shell de comandos, ejecute npm install express. Este comando instala el marco Express.
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.
Abra el archivo Startup.cs y, a continuación, agregue las siguientes declaraciones using al principio de la clase:
C#
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:
C#
publicvoidConfigureServices(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:
C#
app.UseAuthentication();
Después del cambio, el código debe ser parecido al siguiente fragmento de código:
C#
publicvoidConfigure(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();
});
}
Agregue el siguiente código JavaScript al archivo app.js.
JavaScript
// Import the required librariesconst express = require('express');
const morgan = require('morgan');
const passport = require('passport');
const config = require('./config.json');
// Import the passport Azure AD libraryconst BearerStrategy = require('passport-azure-ad').BearerStrategy;
// Set the Azure AD B2C optionsconst options = {
identityMetadata: `https://${config.credentials.tenantName}.b2clogin.com/${config.credentials.tenantName}.onmicrosoft.com/${config.policies.policyName}/${config.metadata.version}/${config.metadata.discovery}`,
clientID: config.credentials.clientID,
audience: config.credentials.clientID,
issuer: config.credentials.issuer,
policyName: config.policies.policyName,
isB2C: config.settings.isB2C,
scope: config.resource.scope,
validateIssuer: config.settings.validateIssuer,
loggingLevel: config.settings.loggingLevel,
passReqToCallback: config.settings.passReqToCallback
}
// Instantiate the passport Azure AD library with the Azure AD B2C optionsconst bearerStrategy = new BearerStrategy(options, (token, done) => {
// Send user info using the second argument
done(null, { }, token);
}
);
// Use the required librariesconst app = express();
app.use(morgan('dev'));
app.use(passport.initialize());
passport.use(bearerStrategy);
//enable CORS (for testing only -remove in production/deployment)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Authorization, Origin, X-Requested-With, Content-Type, Accept');
next();
});
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.
En la carpeta /Controllers, agregue un archivo HelloController.cs y, a continuación, agréguelo al código siguiente:
C#
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Web.Resource;
namespaceTodoList.Controllers
{
[Authorize]
[RequiredScope("tasks.read")]
[ApiController]
[Route("[controller]")]
publicclassHelloController : ControllerBase
{
privatereadonly ILogger<HelloController> _logger;
privatereadonly IHttpContextAccessor _contextAccessor;
publicHelloController(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.
En el archivo app.js, agregue el código JavaScript siguiente:
JavaScript
// API protected endpoint
app.get('/hello',
passport.authenticate('oauth-bearer', {session: false}),
(req, res) => {
console.log('Validated claims: ', req.authInfo);
// Service relies on the name claim.
res.status(200).json({'name': req.authInfo['name']});
}
);
El punto de conexión /hello primero llama a la función passport.authenticate(). La función de autenticación limita el acceso solo a los usuarios autenticados.
La función de autenticación también comprueba que se llama a la API web con los ámbitos adecuados. Los ámbitos permitidos se encuentran en el archivo de configuración.
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.
// Starts listening on port 6000const port = process.env.PORT || 6000;
app.listen(port, () => {
console.log('Listening on port ' + port);
});
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:
JSON
{
"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.
En la carpeta raíz del proyecto, cree un archivo config.json y, a continuación, agréguelo al siguiente fragmento de código JSON:
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.
credentials
issuer
Valor de notificación iss del emisor del token. De forma predeterminada, Azure AD B2C devuelve el token en el formato siguiente: https://<your-tenant-name>.b2clogin.com/<your-tenant-ID>/v2.0/. Reemplace <your-tenant-name> por la primera parte del nombre del inquilino de Azure AD B2C. Reemplace <your-tenant-ID> por el id. del inquilino de Azure AD B2C.
directivas
policyName
Flujos de usuario o directiva personalizada. Para obtener información sobre cómo obtener el flujo de usuario o la directiva, consulte Requisitos previos.
resource
scope
Ámbitos del registro de la aplicación de API web. Para obtener información sobre cómo obtener el ámbito de la API web, 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:
bush
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.
En el shell de comandos, ejecute el siguiente comando para iniciar la aplicación web:
bush
node app.js
Debería ver la siguiente salida, que significa que la aplicación está en funcionamiento y lista para recibir solicitudes.
Example app listening on port 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 node app.js, use 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.
Publique una aplicación de JavaScript de Angular, React, Svelte o Vue con API y autenticación mediante Azure Static Web Apps y Azure Functions. Implemente el código de GitHub en un sitio de ensayo mediante las direcciones URL de vista previa.
Muestre las características de Microsoft Entra ID para modernizar las soluciones de identidad, implementar soluciones híbridas e implementar la gobernanza de identidades.