Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Importante
A partir del 1 de mayo de 2025, Azure AD B2C ya no estará disponible para ser adquirido por nuevos clientes. Obtenga más información en nuestras preguntas más frecuentes.
En este artículo se muestra cómo agregar la autenticación de Azure Active Directory B2C (Azure AD B2C) a su propia aplicación de página única (SPA). Obtenga información sobre cómo crear una aplicación SPA mediante la biblioteca de autenticación de Microsoft para JavaScript (MSAL.js).
Use este artículo con Configuración de la autenticación en una aplicación SPA de ejemplo, sustituyendo la aplicación spa de ejemplo por su propia aplicación spa.
Información general
En este artículo se usa Node.js y Express para crear una aplicación web de Node.js básica. Express es un marco de aplicaciones web Node.js mínimo y flexible que proporciona un conjunto de funciones para aplicaciones web y móviles.
La biblioteca de autenticación MSAL.js es una biblioteca proporcionada por Microsoft que simplifica la adición de compatibilidad con la autenticación y la autorización a las aplicaciones SPA.
Sugerencia
Todo el código MSAL.js se ejecuta en el lado del cliente. Puede sustituir el código del lado del servidor Node.js y Express por otras soluciones, como los lenguajes de scripting .NET Core, Java y Hypertext Preprocessor (PHP).
Prerrequisitos
Para revisar los requisitos previos e instrucciones de integración, consulte Configuración de la autenticación en una aplicación SPA de ejemplo.
Paso 1: Crear un proyecto de aplicación SPA
Puede usar un proyecto de aplicación spa existente o crear uno nuevo. Para crear un proyecto, haga lo siguiente:
Abra un shell de comandos y cree un directorio (por ejemplo, myApp). Este directorio contendrá el código de la aplicación, la interfaz de usuario y los archivos de configuración.
Acceda al directorio que creó.
Use el
npm init
comando para crear unpackage.json
archivo para la aplicación. Este comando te solicita información sobre tu app (por ejemplo, el nombre y la versión de tu app, y el nombre del punto de entrada inicial, el archivo index.js ). Ejecute el comando siguiente y acepte los valores predeterminados:
npm init
Paso 2: Instalación de las dependencias.
Para instalar el paquete Express, en el shell de comandos, ejecute el siguiente comando:
npm install express
Para buscar los archivos estáticos de la aplicación, el código del lado servidor usa el paquete Ruta de acceso .
Para instalar el paquete Path, ejecute el siguiente comando en el shell de comandos:
npm install path
Paso 3: Configurar el servidor web
En la carpeta myApp , cree un archivo denominado index.js, que contiene el siguiente código:
// Initialize express
const express = require('express');
const app = express();
// The port to listen to incoming HTTP requests
const port = 6420;
// Initialize path
const path = require('path');
// Set the front-end folder to serve public assets.
app.use(express.static('App'));
// Set up a route for the index.html
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
});
// Start the server, and listen for HTTP requests
app.listen(port, () => {
console.log(`Listening on http://localhost:${port}`);
});
Paso 4: Creación de la interfaz de usuario de SPA
Agregue el archivo index.html
de la aplicación SPA. Este archivo implementa una interfaz de usuario que se construye con un framework de Bootstrap e importa archivos de script para configuración, autenticación y llamadas a la API web.
Los recursos a los que hace referencia el archivo index.html se detallan en la tabla siguiente:
Referencia | Definición |
---|---|
MSAL.js Biblioteca | Ruta de acceso CDN de la biblioteca de JavaScript de autenticación de MSAL.js. |
Hoja de estilos de bootstrap | Un marco de front-end gratuito para un desarrollo web más rápido y sencillo. El marco incluye plantillas de diseño basadas en HTML y css. |
Para representar el archivo de índice SPA, en la carpeta myApp , cree un archivo denominado index.html, que contiene el siguiente fragmento de código HTML:
<!DOCTYPE html>
<html>
<head>
<title>My Azure AD B2C test app</title>
</head>
<body>
<h2>My Azure AD B2C test app</h2>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
<button type="button" id="signIn" class="btn btn-secondary" onclick="signIn()">Sign-in</button>
<button type="button" id="signOut" class="btn btn-success d-none" onclick="signOut()">Sign-out</button>
<h5 id="welcome-div" class="card-header text-center d-none"></h5>
<br />
<!-- Content -->
<div class="card">
<div class="card-body text-center">
<pre id="response" class="card-text"></pre>
<button type="button" id="callApiButton" class="btn btn-primary d-none" onclick="passTokenToApi()">Call API</button>
</div>
</div>
<script src="https://alcdn.msauth.net/browser/2.14.2/js/msal-browser.min.js" integrity="sha384-ggh+EF1aSqm+Y4yvv2n17KpurNcZTeYtUZUvhPziElsstmIEubyEB6AIVpKLuZgr" crossorigin="anonymous"></script>
<!-- Importing app scripts (load order is important) -->
<script type="text/javascript" src="./apiConfig.js"></script>
<script type="text/javascript" src="./policies.js"></script>
<script type="text/javascript" src="./authConfig.js"></script>
<script type="text/javascript" src="./ui.js"></script>
<!-- <script type="text/javascript" src="./authRedirect.js"></script> -->
<!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
<script type="text/javascript" src="./authRedirect.js"></script>
<script type="text/javascript" src="./api.js"></script>
</body>
</html>
Paso 5: Configurar la biblioteca de autenticación
Configure cómo se integra la biblioteca de MSAL.js con Azure AD B2C. La biblioteca MSAL.js usa un objeto de configuración común para conectarse a los puntos de conexión de autenticación del inquilino de Azure AD B2C.
Para configurar la biblioteca de autenticación, haga lo siguiente:
En la carpeta myApp , cree una carpeta denominada App.
Dentro de la carpeta Aplicación , cree un nuevo archivo denominado authConfig.js.
Agregue el siguiente código JavaScript al archivo authConfig.js :
const msalConfig = { auth: { clientId: "<Application-ID>", authority: b2cPolicies.authorities.signUpSignIn.authority, knownAuthorities: [b2cPolicies.authorityDomain], redirectUri: "http://localhost:6420", }, cache: { cacheLocation: "localStorage", . storeAuthStateInCookie: false, } }; const loginRequest = { scopes: ["openid", ...apiConfig.b2cScopes], }; const tokenRequest = { scopes: [...apiConfig.b2cScopes], forceRefresh: false };
Reemplace
<Application-ID>
por el id. de la aplicación de registro de la aplicación. Para obtener más información, consulte Configuración de la autenticación en una aplicación SPA de ejemplo.
Sugerencia
Para obtener más opciones de configuración de objetos MSAL, consulte el artículo Opciones de autenticación .
Paso 6: Especificar los flujos de usuario de Azure AD B2C
Cree el archivo policies.js , que proporciona información sobre el entorno de Azure AD B2C. La biblioteca MSAL.js usa esta información para crear solicitudes de autenticación a Azure AD B2C.
Para especificar los flujos de usuario de Azure AD B2C, haga lo siguiente:
Dentro de la carpeta Aplicación , cree un nuevo archivo denominado policies.js.
Agregue el siguiente código al archivo policies.js :
const b2cPolicies = { names: { signUpSignIn: "B2C_1_SUSI", editProfile: "B2C_1_EditProfile" }, authorities: { signUpSignIn: { authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-SignInOrSignUp-Policy-Id", }, editProfile: { authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-EditProfile-Policy-Id" } }, authorityDomain: "contoso.b2clogin.com" }
Reemplace
B2C_1_SUSI
por el nombre de directiva de inicio de sesión de Azure AD B2C.Reemplace
B2C_1_EditProfile
por el nombre de directiva de edición de perfiles de Azure AD B2C.Reemplace todas las instancias de
contoso
por el nombre del inquilino de Azure AD B2C.
Paso 7: Uso de MSAL para iniciar sesión en el usuario
En este paso, implemente los métodos para inicializar el flujo de inicio de sesión, la adquisición de tokens de acceso de API y los métodos de cierre de sesión.
Para obtener más información, consulte el artículo Uso de la biblioteca de autenticación de Microsoft (MSAL) para iniciar sesión en el usuario .
Para iniciar sesión en el usuario, haga lo siguiente:
Dentro de la carpeta Aplicación , cree un nuevo archivo denominado authRedirect.js.
En su authRedirect.js, copie y pegue el siguiente código:
// Create the main myMSALObj instance // configuration parameters are located at authConfig.js const myMSALObj = new msal.PublicClientApplication(msalConfig); let accountId = ""; let idTokenObject = ""; let accessToken = null; myMSALObj.handleRedirectPromise() .then(response => { if (response) { /** * For the purpose of setting an active account for UI update, we want to consider only the auth response resulting * from SUSI flow. "tfp" claim in the id token tells us the policy (NOTE: legacy policies may use "acr" instead of "tfp"). * To learn more about B2C tokens, visit https://learn.microsoft.com/azure/active-directory-b2c/tokens-overview */ if (response.idTokenClaims['tfp'].toUpperCase() === b2cPolicies.names.signUpSignIn.toUpperCase()) { handleResponse(response); } } }) .catch(error => { console.log(error); }); function setAccount(account) { accountId = account.homeAccountId; idTokenObject = account.idTokenClaims; myClaims= JSON.stringify(idTokenObject); welcomeUser(myClaims); } function selectAccount() { /** * See here for more information on account retrieval: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md */ const currentAccounts = myMSALObj.getAllAccounts(); if (currentAccounts.length < 1) { return; } else if (currentAccounts.length > 1) { /** * Due to the way MSAL caches account objects, the auth response from initiating a user-flow * is cached as a new account, which results in more than one account in the cache. Here we make * sure we are selecting the account with homeAccountId that contains the sign-up/sign-in user-flow, * as this is the default flow the user initially signed-in with. */ const accounts = currentAccounts.filter(account => account.homeAccountId.toUpperCase().includes(b2cPolicies.names.signUpSignIn.toUpperCase()) && account.idTokenClaims.iss.toUpperCase().includes(b2cPolicies.authorityDomain.toUpperCase()) && account.idTokenClaims.aud === msalConfig.auth.clientId ); if (accounts.length > 1) { // localAccountId identifies the entity for which the token asserts information. if (accounts.every(account => account.localAccountId === accounts[0].localAccountId)) { // All accounts belong to the same user setAccount(accounts[0]); } else { // Multiple users detected. Logout all to be safe. signOut(); }; } else if (accounts.length === 1) { setAccount(accounts[0]); } } else if (currentAccounts.length === 1) { setAccount(currentAccounts[0]); } } // in case of page refresh selectAccount(); async function handleResponse(response) { if (response !== null) { setAccount(response.account); } else { selectAccount(); } } function signIn() { myMSALObj.loginRedirect(loginRequest); } function signOut() { const logoutRequest = { postLogoutRedirectUri: msalConfig.auth.redirectUri, }; myMSALObj.logoutRedirect(logoutRequest); } function getTokenRedirect(request) { request.account = myMSALObj.getAccountByHomeId(accountId); return myMSALObj.acquireTokenSilent(request) .then((response) => { // In case the response from B2C server has an empty accessToken field // throw an error to initiate token acquisition if (!response.accessToken || response.accessToken === "") { throw new msal.InteractionRequiredAuthError; } else { console.log("access_token acquired at: " + new Date().toString()); accessToken = response.accessToken; passTokenToApi(); } }).catch(error => { console.log("Silent token acquisition fails. Acquiring token using popup. \n", error); if (error instanceof msal.InteractionRequiredAuthError) { // fallback to interaction when silent call fails return myMSALObj.acquireTokenRedirect(request); } else { console.log(error); } }); } // Acquires and access token and then passes it to the API call function passTokenToApi() { if (!accessToken) { getTokenRedirect(tokenRequest); } else { try { callApi(apiConfig.webApi, accessToken); } catch(error) { console.log(error); } } } function editProfile() { const editProfileRequest = b2cPolicies.authorities.editProfile; editProfileRequest.loginHint = myMSALObj.getAccountByHomeId(accountId).username; myMSALObj.loginRedirect(editProfileRequest); }
Paso 8: Configuración de la ubicación y el ámbito de la API web
Para permitir que la aplicación spa llame a una API web, proporcione la ubicación del punto de conexión de la API web y los ámbitos que se usarán para autorizar el acceso a la API web.
Para configurar la ubicación y los ámbitos de la API web, haga lo siguiente:
Dentro de la carpeta Aplicación , cree un nuevo archivo denominado apiConfig.js.
En su apiConfig.js, copie y pegue el siguiente código:
// The current application coordinates were pre-registered in a B2C tenant. const apiConfig = { b2cScopes: ["https://contoso.onmicrosoft.com/tasks/tasks.read"], webApi: "https://mydomain.azurewebsites.net/tasks" };
Remplace
contoso
por el nombre del inquilino. El nombre de ámbito necesario se puede encontrar como se describe en el artículo Configuración de ámbitos .Reemplace el valor de
webApi
por su ubicación de punto de conexión de API web.
Paso 9: Llamada a la API web
Defina la solicitud HTTP al punto de conexión de API. La solicitud HTTP está configurada para pasar el token de acceso que se adquirió con MSAL.js en el encabezado HTTP de la solicitud Authorization
.
El siguiente código define la solicitud HTTP GET
para el punto de conexión de la API, pasando el token de acceso en el encabezado HTTP Authorization
. La ubicación de la API está definida por la clave webApi
.
Para llamar a la API web mediante el token que adquirió, haga lo siguiente:
Dentro de la carpeta Aplicación , cree un nuevo archivo denominado api.js.
Agregue el siguiente código al archivo api.js :
function callApi(endpoint, token) { const headers = new Headers(); const bearer = `Bearer ${token}`; headers.append("Authorization", bearer); const options = { method: "GET", headers: headers }; logMessage('Calling web API...'); fetch(endpoint, options) .then(response => response.json()) .then(response => { if (response) { logMessage('Web API responded: ' + response.name); } return response; }).catch(error => { console.error(error); }); }
Paso 10: Agregar la referencia de elementos de la interfaz de usuario
La aplicación SPA usa JavaScript para controlar los elementos de la interfaz de usuario. Por ejemplo, visualiza los botones de inicio de sesión y cierre de sesión y muestra las reclamaciones del token de identificación de los usuarios en la pantalla.
Para agregar la referencia de elementos de la interfaz de usuario, haga lo siguiente:
Dentro de la carpeta App , cree un archivo llamado ui.js.
Agregue el siguiente código al archivo ui.js :
// Select DOM elements to work with const signInButton = document.getElementById('signIn'); const signOutButton = document.getElementById('signOut') const titleDiv = document.getElementById('title-div'); const welcomeDiv = document.getElementById('welcome-div'); const tableDiv = document.getElementById('table-div'); const tableBody = document.getElementById('table-body-div'); const editProfileButton = document.getElementById('editProfileButton'); const callApiButton = document.getElementById('callApiButton'); const response = document.getElementById("response"); const label = document.getElementById('label'); function welcomeUser(claims) { welcomeDiv.innerHTML = `Token claims: </br></br> ${claims}!` signInButton.classList.add('d-none'); signOutButton.classList.remove('d-none'); welcomeDiv.classList.remove('d-none'); callApiButton.classList.remove('d-none'); } function logMessage(s) { response.appendChild(document.createTextNode('\n' + s + '\n')); }
Paso 11: Ejecución de la aplicación SPA
En el shell de comandos, ejecute los siguientes comandos:
npm install
npm ./index.js
- Vaya a https://localhost:6420.
- Seleccione Iniciar sesión.
- Complete el proceso de inicio de sesión o registro.
Después de autenticarse correctamente, el token de identificador analizado se muestra en la pantalla. Seleccione Call API
para llamar a su punto de conexión de API.
Pasos siguientes
- Obtenga más información sobre el ejemplo de código.
- Configure las opciones de autenticación en su propia aplicación de página única mediante Azure AD B2C.
- Habilitación de la autenticación en su propia API web.