Configuración de la autenticación en una aplicación de página única mediante Azure AD B2C

En este artículo se usa un ejemplo de aplicación de página única (SPA) para ilustrar cómo agregar la autenticación de Azure Active Directory B2C (Azure AD B2C) a sus aplicaciones SPA.

Información general

OpenID Connect (OIDC) es un protocolo de autenticación que se basa en OAuth 2.0. Puede usarlo para que un usuario inicie sesión en una aplicación de manera segura. Este ejemplo de SPA usa MSAL.js y el flujo PKCE de OIDC. MSAL.js es una biblioteca proporcionada por Microsoft que simplifica la adición de compatibilidad con autenticación y autorización a las aplicaciones SPA.

Flujo de inicio de sesión

El flujo de inicio de sesión consta de los pasos siguientes:

  1. El usuario va a la aplicación web y selecciona Iniciar sesión.
  2. La aplicación inicia la solicitud de autenticación y redirige a los usuarios a Azure AD B2C.
  3. Los usuarios se registran o inician sesión y restablecen la contraseña. También pueden iniciar sesión con una cuenta de red social.
  4. Una vez que los usuarios inician sesión, Azure AD B2C devuelve un código de autorización a la aplicación.
  5. La aplicación de página única valida el token de identificador, lee las notificaciones y, a su vez, permite a los usuarios llamar a recursos o API protegidos.

Introducción al registro de aplicaciones

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

  • El registro de la aplicación web permite que la aplicación inicie sesión con Azure AD B2C. Durante el registro, hay que especificar el URI de redirección. El URI de redirección es el punto de conexión al que Azure AD B2C redirige a los usuarios después de que se autentican en este servicio. El proceso de registro de la aplicación genera un identificador de aplicación, también conocido como identificador de cliente, que permite identificar de forma exclusiva la aplicación.

  • El registro de API web permite que la aplicación llame a una API web segura. El registro incluye los ámbitos de la API web. Los ámbitos ofrecen una manera de administrar permisos para los recursos protegidos, como la API web. A la aplicación web se le conceden permisos para los ámbitos de la API web. Cuando se selecciona un token de acceso, la aplicación especifica los permisos que desea en el parámetro de ámbito de la solicitud.

En el siguiente diagrama se muestran los registros y la arquitectura de la aplicación:

Diagram of a web app with web API call registrations and tokens.

Llamada a una API web

Una vez completada la autenticación, los usuarios interactúan con la aplicación, que invoca una API web protegida. La API web usa la autenticación de token de portador. El token de portador es el token de acceso que la aplicación ha obtenido de Azure Active Directory B2C. La aplicación pasa el token en el encabezado de autorización de la solicitud HTTPS.

Authorization: Bearer <access token>

Si el ámbito del token de acceso no coincide con los ámbitos de la API web, la biblioteca de autenticación obtiene un nuevo token de acceso con los ámbitos correctos.

Flujo de cierre de sesión

El flujo de cierre de sesión consta de los siguientes pasos:

  1. En la aplicación, los usuarios cierran sesión.
  2. La aplicación borra sus objetos de sesión y la biblioteca de autenticación borra su caché de tokens.
  3. La aplicación lleva a los usuarios al punto de conexión de cierre de sesión de Azure AD B2C para finalizar la sesión correspondiente a este.
  4. Los usuarios se redirigen de nuevo a la aplicación.

Prerrequisitos

Un equipo que ejecute:

Paso 1: Configuración del flujo de usuario

Cuando los usuarios intentan iniciar sesión en la aplicación, esta inicia una solicitud de autenticación para el punto de conexión de autorización mediante un flujo de usuario. El flujo de usuario define y controla la experiencia del usuario. Al completar los usuarios el flujo de usuario, Azure AD B2C genera un token y, después, redirige a los usuarios de vuelta a la aplicación.

Si aún no lo ha hecho, cree un flujo de usuario o una directiva personalizada. Repita los pasos para crear tres flujos de usuario independientes de la manera siguiente:

  • Un flujo de usuario combinado de inicio de sesión y registro, como susi. Este flujo de usuario también admite la experiencia ¿Olvidó su contraseña?.
  • Un flujo de usuario de edición de perfiles, como edit_profile.
  • Un flujo de usuario de restablecimiento de contraseña, como reset_password.

Azure AD B2C antepone el prefijo B2C_1_ al nombre del flujo de usuario. Por ejemplo, susi se convierte en B2C_1_susi.

Paso 2: Registro de la SPA y la API

En este paso, creará la aplicación SPA y los registros de aplicación de API web, y especificará los ámbitos de la API web.

Paso 2.1: Registro de la aplicación de API web

Siga estos pasos para crear el registro de aplicación de API web (Id. de aplicación: 2):

  1. Inicie sesión en Azure Portal.

  2. Asegúrese de que usa el directorio que contiene el inquilino de Azure AD B2C. Seleccione el icono Directorios y suscripciones en la barra de herramientas del portal.

  3. En la página Configuración del portal | Directorios y suscripciones, busque el directorio de Azure AD B2C en la lista Nombre de directorio y seleccione Cambiar.

  4. En Azure Portal, busque y seleccione Azure AD B2C.

  5. Seleccione Registros de aplicaciones y luego Nuevo registro.

  6. En Nombre, escriba un nombre para la aplicación (por ejemplo, my-api1). Deje los valores predeterminados para URI de redireccionamiento y Tipos de cuenta admitidos.

  7. Seleccione Registrar.

  8. Una vez completado el registro de la aplicación, seleccione Información general.

  9. Anote el valor Id. de aplicación (cliente) para usarlo más adelante al configurar la aplicación web.

    Screenshot that demonstrates how to get a web A P I application I D.

Paso 2.2: Configuración de ámbitos

  1. Seleccione la aplicación my-api1 que creó (id. de aplicación: 2) para abrir la página Información general.

  2. En Administrar, seleccione Exponer una API.

  3. Junto a URI de id. de aplicación, seleccione el vínculo Establecer. Reemplace el valor predeterminado (GUID) por un nombre único (por ejemplo, tasks-api) y, luego, seleccione Guardar.

    Cuando la aplicación web solicite un token de acceso para la API web, deberá agregar este URI como prefijo para cada ámbito que se defina para la API.

  4. En Ámbitos definidos con esta API, seleccione Agregar un ámbito.

  5. Para crear un ámbito que defina el acceso de lectura a la API, siga estos pasos:

    1. Para Nombre de ámbito, escriba tasks.read.
    2. Para Nombre para mostrar del consentimiento del administrador, escriba Acceso de lectura a la API de tareas.
    3. Para Descripción del consentimiento del administrador, escriba Permite el acceso de lectura a la API de tareas.
  6. Seleccione la opción Agregar un ámbito.

  7. Seleccione Agregar un ámbito y agregue una opción que defina el acceso de escritura en la API:

    1. Para Nombre de ámbito, escriba tasks.write.
    2. Para Nombre para mostrar del consentimiento del administrador, escriba Acceso de escritura a la API de tareas.
    3. Para Descripción del consentimiento del administrador, escriba Permite el acceso de escritura a la API de tareas.
  8. Seleccione la opción Agregar un ámbito.

Paso 2.3: Registro de la SPA

Para crear el registro de la SPA, siga estos pasos:

  1. Inicie sesión en Azure Portal.
  2. Si tiene acceso a varios inquilinos, seleccione el icono Configuración en el menú superior para cambiar a su inquilino de Azure AD B2C desde el menú Directorios y suscripciones.
  3. Busque y seleccione Azure AD B2C.
  4. Seleccione Registros de aplicaciones y luego Nuevo registro.
  5. Escriba un Nombre para la aplicación (por ejemplo, MyApp).
  6. En Tipos de cuenta compatibles, seleccione Cuentas en cualquier proveedor de identidades o directorio de la organización (para autenticar usuarios con flujos de usuario) .
  7. En URI de redirección, seleccione Aplicación de página única (SPA) y, a continuación, escriba http://localhost:6420 en el cuadro de texto de dirección URL.
  8. En Permisos, active la casilla Conceder consentimiento de administrador para openid y permisos de acceso sin conexión.
  9. Seleccione Registrar.

Anote el Id. de aplicación (cliente) para usarlo más adelante al configurar la aplicación web.

Screenshot of the web app Overview page for recording your web application ID.

Paso 2.4: Habilitación del flujo de concesión implícita

En su propio entorno, si la aplicación SPA usa MSAL.js 1.3 o versiones anteriores y el flujo de concesión implícita o configura la aplicación https://jwt.ms/ para probar un flujo de usuario o una directiva personalizada, debe habilitar el flujo de concesión implícita en el registro de la aplicación:

  1. En el menú izquierdo, en Administrar, seleccione Autenticación.

  2. En Flujos híbridos y de concesión implícita, seleccione las casillas Tokens de acceso (para flujos implícitos) y Tokens de id. (para flujos híbridos e implícitos).

  3. Seleccione Guardar.

Si la aplicación usa MSAL.js 2.0 o versiones posteriores, no habilite la concesión de flujo implícita, ya que MSAL.js 2.0+ admite el flujo de código de autorización con PKCE. La aplicación SPA de este artículo usa el flujo PKCE, por lo que no es necesario habilitar el flujo de concesión implícita.

Paso 2.5: Concesión de permisos

Si desea conceder permisos a la aplicación (identificador de aplicación: 1), siga estos pasos:

  1. Seleccione Registros de aplicaciones y, luego, la aplicación que creó (identificador de aplicación: 1).

  2. En Administrar, seleccione Permisos de API.

  3. En Permisos configurados, seleccione Agregar un permiso.

  4. Seleccione la pestaña Mis API.

  5. Seleccione la API (identificador de aplicación:2) a la que la aplicación web debe tener acceso. Por ejemplo, escriba my-api1.

  6. En Permiso, expanda Tareas y, a continuación, seleccione los ámbitos que definió anteriormente; por ejemplo, tasks.read y tasks.write.

  7. Seleccione Agregar permisos.

  8. Seleccione Conceder consentimiento de administrador para <el nombre de inquilino>.

  9. Seleccione .

  10. Seleccione Actualizar y compruebe que aparece Granted for... (Concedido para...) en Estado para ambos ámbitos.

  11. En la lista Permisos configurados, seleccione el ámbito y copie el nombre completo del ámbito.

    Screenshot of the configured permissions pane, showing that read access permissions are granted.

Paso 3: Obtención del código de ejemplo de SPA

En este ejemplo se muestra cómo una aplicación de página única puede usar Azure AD B2C para el registro e inicio de sesión de usuarios. A continuación, la aplicación adquiere un token de acceso y llama a una API web protegida.

Para obtener el código de ejemplo de la aplicación SPA, puede realizar una de las acciones siguientes:

  • Descargue un archivo ZIP.

  • Clone el ejemplo de GitHub ejecutando el comando siguiente:

    git clone https://github.com/Azure-Samples/ms-identity-b2c-javascript-spa.git
    

Paso 3.1: Actualización del ejemplo de SPA

Ahora que ha obtenido el ejemplo de SPA, actualice el código con sus valores de Azure AD B2C y la API web. En la carpeta App de la carpeta de ejemplo, abra los archivos de JavaScript que se muestran en la tabla siguiente y, luego, actualícelos con los valores correspondientes.

Archivo Clave Valor
authConfig.js clientId El id. de la aplicación SPA del paso 2.3.
policies.js nombres Los flujos de usuario o la directiva personalizada que creó en el paso 1.
policies.js autoridades Los flujos de usuario o las entidades de directivas personalizadas de Azure AD B2C, como https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<your-sign-in-sign-up-policy>. Reemplace your-sign-in-sign-up-policy por el flujo de usuario o la directiva personalizada que creó en el paso 1
policies.js authorityDomain El dominio de la entidad de Azure AD B2C, como <your-tenant-name>.b2clogin.com.
apiConfig.js b2cScopes Los ámbitos de API web que creó en el paso 2.2 (por ejemplo, b2cScopes: ["https://<your-tenant-name>.onmicrosoft.com/tasks-api/tasks.read"]).
apiConfig.js webApi Dirección URL de la API web, http://localhost:5000/hello.

El código resultante tendrá un aspecto similar al del ejemplo siguiente:

authConfig.js:

const msalConfig = {
    auth: {
      clientId: "<your-MyApp-application-ID>", // This is the ONLY mandatory field; everything else is optional.
      authority: b2cPolicies.authorities.signUpSignIn.authority, // Choose sign-up/sign-in user-flow as your default.
      knownAuthorities: [b2cPolicies.authorityDomain], // You must identify your tenant's domain as a known authority.
      redirectUri: "http://localhost:6420", // You must register this URI on Azure Portal/App Registration. Defaults to "window.location.href".
    },
    cache: {
      cacheLocation: "sessionStorage",  
      storeAuthStateInCookie: false, 
    },
    system: {
      loggerOptions: {
        loggerCallback: (level, message, containsPii) => {
          if (containsPii) {
            return;
          }
          switch (level) {
            case msal.LogLevel.Error:
              console.error(message);
              return;
            case msal.LogLevel.Info:
              console.info(message);
              return;
            case msal.LogLevel.Verbose:
              console.debug(message);
              return;
            case msal.LogLevel.Warning:
              console.warn(message);
              return;
          }
        }
      }
    }
  };
};

const loginRequest = {
  scopes: ["openid", ...apiConfig.b2cScopes],
};

const tokenRequest = {
  scopes: [...apiConfig.b2cScopes],  // e.g. ["https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"]
  forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};

policies.js:

const b2cPolicies = {
    names: {
        signUpSignIn: "b2c_1_susi",
        forgotPassword: "b2c_1_reset",
        editProfile: "b2c_1_edit_profile"
    },
    authorities: {
        signUpSignIn: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_susi",
        },
        forgotPassword: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_reset",
        },
        editProfile: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_edit_profile"
        }
    },
    authorityDomain: "your-tenant-name.b2clogin.com"
}

apiConfig.js:

const apiConfig = {
  b2cScopes: ["https://your-tenant-name.onmicrosoft.com/tasks-api/tasks.read"],
  webApi: "http://localhost:5000/hello"
};

Paso 4: Obtención del código de ejemplo de la API web

Ahora que ha registrado la API web y ha definido sus ámbitos, configure el código de la API web para que funcione con el inquilino de Azure AD B2C.

Para obtener el código de ejemplo de la API web, haga una de las acciones siguientes:

Paso 4.1: Actualización de la API web

  1. Abra el archivo config.json en el editor de código.

  2. Modifique los valores de las variables con el registro de aplicación creado anteriormente. Y actualice policyName con el flujo de usuario que creó como parte de los requisitos previos (por ejemplo, b2c_1_susi).

    "credentials": {
        "tenantName": "<your-tenant-name>",
        "clientID": "<your-webapi-application-ID>"
    },
    "policies": {
        "policyName": "b2c_1_susi"
    },
    "resource": {
        "scope": ["tasks.read"] 
    },
    

Paso 4.2: Habilitación de CORS

Para permitir que la aplicación de página única llame a la API web de Node.js, debe habilitar el uso compartido de recursos entre orígenes (CORS) en la API web. En una aplicación de producción, tenga cuidado con el dominio que realiza la solicitud. En este ejemplo, permite solicitudes de cualquier dominio.

Para habilitar CORS, utilice el siguiente middleware. En el código de ejemplo de la API web de Node.js que descargó, ya se ha agregado al archivo index.js.

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 5: Ejecución de la SPA y la API web

Ya está preparado para probar el acceso de ámbito de la aplicación de página única a la API. Ejecute la API web de Node.js y la aplicación de página única de JavaScript de ejemplo en la máquina local. A continuación, inicie sesión en la aplicación de página única y seleccione el botón Call API (Llamar a la API) para iniciar una solicitud a la API protegida.

Ejecución de la API web de Node.js

  1. Abra una ventana de consola y cambie al directorio que contiene la API web de Node.js de ejemplo. Por ejemplo:

    cd active-directory-b2c-javascript-nodejs-webapi
    
  2. Ejecute los comandos siguientes:

    npm install && npm update
    node index.js
    

    La ventana de la consola muestra el número de puerto en el que se hospeda la aplicación.

    Listening on port 5000...
    

Ejecución de una aplicación de página única

  1. Abra otra ventana de consola y cambie al directorio que contiene la aplicación de página única de JavaScript de ejemplo. Por ejemplo:

    cd ms-identity-b2c-javascript-spa
    
  2. Ejecute los comandos siguientes:

    npm install && npm update
    npm start
    

    La ventana de la consola muestra el número de puerto donde se hospeda la aplicación.

    Listening on port 6420...
    
  3. Para ver la aplicación, vaya a http://localhost:6420 en el explorador.

    Screenshot of the SPA sample app displayed in the browser window.

  4. Complete el proceso de inicio de sesión o registro. Una vez que inicie sesión correctamente, debería ver el mensaje "User <your username> logged in" (El usuario inició sesión).

  5. Seleccione el botón Llamada a API. La SPA envía el token de acceso en una solicitud a la API web protegida, que devuelve el nombre para mostrar del usuario que ha iniciado sesión:

    Screenshot of the SPA in a browser window, showing the username JSON result that's returned by the API.

Implementación de aplicación

En una aplicación de producción, el URI de redirección del registro de la aplicación suele ser un punto de conexión accesible públicamente donde se ejecuta la aplicación, como https://contoso.com/signin-oidc.

Puede agregar y modificar los URI de redireccionamiento en las aplicaciones registradas en cualquier momento. Las siguientes restricciones se aplican a los URI de redireccionamiento:

  • La dirección URL de respuesta debe comenzar con el esquema https.
  • La dirección URL de respuesta distingue mayúsculas de minúsculas. Sus mayúsculas o minúsculas deben coincidir con las de la ruta de acceso de la dirección URL de la aplicación en ejecución.

Pasos siguientes

Para más información sobre los conceptos que se tratan en este artículo: