Azure AD B2C es un servicio brillante que nos permite generar flujos para inicio de sesión, registro, recupero de contraseña, etc., en forma muy simple y rápida sin necesidad de escribir código.

Sin embargo, en ocasiones es necesario implementar nuestra propia hoja de estilos de forma que los usuarios tengan una experiencia totalmente integrada.

En este artículo veremos como personalizar nuestras vistas aplicando hojas de estilos propias.

Contexto

Cuándo desarrollamos aplicaciones web, uno de los factores determinantes para el éxito o el fracaso de nuestra aplicación es la experiencia de usuario o UX.

Un estilo o diseño consistente favorece la experiencia de usuario haciendo la utilización más intuitiva y una navegación más fluida.

Si bien Azure AD B2C ofrece flujos de usuario con vistas listas para usar y diseños estándares, puede que no sean consistentes con el resto de nuestra aplicació y necesitemos implementar nuestra propia hoja de estilos.

Requerimiento

Ya tenemos configurado nuestro flujo de usuario unificado para registro o inicio de sesión incluyendo algunos proveedores externos.

Inicio de sesión estándar
Inicio de sesión estándar

Ahora necesitamos que la lista de proveedores externos se muestre primero, es decir, antes de la opción con Email y Contraseña.

Para lograr implementar este requerimiento es necesario realizar algunas modificaciones al código css.

¿Cómo funciona?

Cada flujo de usuario está compuesto por una serie de vistas. A su vez, cada vista tiene asociado un archivo de estilos particular.

Desde el panel del flujo de usuario, navegaremos a la sección Diseños de Página para acceder a la lista de vistas que componen el flujo actual.

Lista de diseños de páginas
Lista de diseños de páginas

Como podemos apreciar en la imagen anterior, cada diseño de página tiene la opción de utilizar contenido personalizado, y en el caso de activar esta opción podremos indicar la URI de la página personalizada.

Página personalizada

Para poder utilizar nuestra página personalizada podemos usar un archivo *.html estático, o también páginas dinámicas como .NET, NodeJS o PHP.

El código HTML puede contener cualquier elemento, el único requerimiento es un elemento div con id igual a "api", como en el siguiente ejemplo:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div id="api"></div>
</body>
</html>

Azure AD B2C agregará todos los elementos necesarios dentro del div mencionado anteriormente.

Dentro de este HTML podemos incluir referencias a archivos *.css o *.js, el único requerimiento es que estos archivos sean accesibles públicamente mediante HTTPS.

Plantillas predefinidas

Si bien tenemos la opción de utilizar HTML totalmente personalizado, Azure AD B2C nos ofrece plantillas completas que podemos utilizar como base.

Sobre estas plantillas base haremos nuestros cambios. Esto hace mucho más simple la personalización.

Podemos descargar las platillas base desde aquí.

Hosting

Las plantillas personalizadas que crearemos deben poder ser accedidas en forma pública mediante una petición GET HTTPS.

Podemos utilizar cualquier tipo de servicio a tal fin, como Azure Web Apps, Azure Functions, una aplicación web Node.js, etc.

Para este ejemplo utilizaremos un archivo *.html estático almacenado en un blob de Azure Storage.

Queda fuera del alcance de este artículo la configuración de Azure Storage. Puedes visitar la documentación oficial para encontrar instrucciones paso a paso al respecto.

Prueba inicial

Para entender cómo funcionan las plantillas personalizadas comenzaremos haciendo una prueba muy simple. Crearemos un archivo llamado index.html cuyo único contenido será un Título de página.

Este archivo no contendrá ningún estilo css ni ningún otro elemento html, solo el div con id "api" y un elemento title:

<!DOCTYPE html>
<html>
<head>
    <title>Prueba inicial</title>
</head>
<body>
    <div id="api"></div>
</body>
</html>

Debemos subir este archivo a Azure Storage y asegurarnos que es de público acceso. Al finalizar, tomar nota de la URI de acceso.

Finalmente, actualizaremos el diseño de página para utilizar como plantilla personalizada la URI que copiamos en el paso anterior.

Luego de guardar los cambios y ejecutar el flujo de usuario, deberíamos obtener el siguiente resultado:

Inicio de sesión sin estilo
Inicio de sesión sin estilo

Implementación del requerimiento

Para poder implementar el requerimiento, vamos a partir de la plantilla por defecto que Azure AD B2C utiliza. Podemos obtener este diseño desde la misma vista donde configuramos la vista personalizada.

Una vez descargada la plantilla, podemos hacer las modificaciones que necesitamos sobre la misma en función de nuestras necesidades.

Para implementar satisfactoriamente nuestro requerimiento, necesitamos alterar el estilo del elemento div con id "api" de forma que ordene los elementos interiores de forma inversa, para eso combinaremos las propiedades display: flex y flex-direction: column-reverse.

Agregaremos un atributo style al elemento con el valor "flex-direction: column-reverse; display: flex;" como se muestra a continuación:

<html>
<head>
  <title>Sign up or sign in</title>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css">
  <style id="common">...</style>
  <style id="idpselector">...</style>
  <style>...</style>
  <style>...</style>
  <script type="text/javascript" src="chrome-extension://lbdfknhegglkmkgffjecdpodddfnibpb/inject.js"></script>
</head>
<body data-new-gr-c-s-check-loaded="14.1010.0" data-gr-ext-installed="">
  <div id="background_branding_container" data-tenant-branding-background-color="true">
    <img data-tenant-branding-background="true" ...>
  </div>
  <div class="container  unified_container " role="presentation">
      <div class="row">
          <div class="col-lg-6">
              <div class="panel panel-default">
                  <div class="panel-body">
                      <img class="companyLogo" data-tenant-branding-logo="true" ...>
                      <div id="api" style="flex-direction: column-reverse;display: flex;">
                      </div>
                  </div>
              </div>
          </div>
      </div>
  </div>
  <div id="mfa_inject_cartdata" hidden="hidden"></div>
  <div id="mfa_inject" hidden="hidden"></div>
</body>
</html>

Una vez realizado el cambio en el archivo, lo subiremos a Azure Storage como hicimos anteriormente y guardamos la URI correspondiente.

Una vez guardados los cambios, ejecutaremos el flujo de usuario nuevamente. Esta vez la lista de proveedores externos aparecerá primero, antes de la opción Email y Contraseña.

Inicio de sesión con diseño modificado
Inicio de sesión con diseño modificado

El equipo de desarrolladores de Azure AD B2C puede ir cambiando el html por defecto con el tiempo, en todos los casos donde se requieran personalizaciones como esta, es recomendable analizar cuidadosamente y familiarizarse con la hoja de estilos provista.

Consideraciones

En este ejemplo partimos de una plantilla base e hicimos cambios casi triviales para satisfascer el requerimiento. Sin embargo en ocasiones los cambios serán mucho más complejos.

Cabe destacar que además de poder incluir elementos html adicionales y estilos css, también podemos incluir código JavaScript, ya sea embebido o referenciando archivos externos.

JavaScript

Para poder incluir código JavaScript, ya sea mediante código embebido o archivos externos, necesitamos habilitar su uso desde la sección Propiedades del flujo de usuario.

Habilitar JavaScript
Habilitar JavaScript

Por cuestiones de seguridad, Azure AD B2C tiene ciertas restricciones en cuánto a JavaScript que pueden ir variando con el tiempo. Es recomendable leer atentamente la documentación oficial.

iframes

Los elementos del tipo iframe son considerados inseguros, razón por la cuál no son soportados por Azure AD B2C.

Conclusión

Azure AD B2C nos ofrece la posibilidad de tener un control total sobre la hoja de estilos de cada una de las vistas.

Gracias a este control y la posibilidad de incluir nuestro propio código css, html y js, podremos crear experiencias de usuario totalmente consistentes con el resto de nuestra aplicación.