Módulo PrestaShop: Cliente OAuth 2.0 para single SignOn

Módulo PrestaShop: Cliente OAuth 2.0 para single SignOn

Módulo PrestaShop gratuito para crear un proceso de inicio de sesión único (single signon) en el que tu tienda actúa como cliente de un Servidor de Identidades central a través de la tecnología OAuth 2.0.

Muchas webs —cada día mas— te ofrecen la posibilidad de registrarte y acceder a ellas usando tus credenciales en otra plataforma. Típicamente una red social como Twitter, Facebook … o con tu cuenta de Google. Cuando utilizas esta facilidad, estás usando la tecnología OAuth que es una API que permite realizar una autorización segura entre dos sitios entre los que se crea una relación de confianza.

Hay muchos módulos PrestaShop que te permiten usar esta tecnología en tu tienda para conectarte con tus perfiles sociales. Pero el módulo que te presento aquí no sirve para esto.

El problema que se pretende resolver es otro. Se trata de crear una infraestructura de inicio de sesión único (single signon) para una web que forma parte de una red corporativa, de forma que un usuario pueda mantener unas credenciales de acceso (típicamente un usuario y una contraseña) que sean únicas para todas las webs y aplicaciones de la corporación, a la vez que solo se le pida presentar sus credenciales una vez, y no cada vez que acceda a una de las webs o aplicaciones.

Esto significa que para usar este módulo necesitas disponer de un servidor OAuth 2.0 dentro de tu organización, y tener acceso a él para poder crear la relación de confianza que permite que OAuth funcione.

Este artículo se centra en el módulo PrestaShop gratuito que permite incluir una tienda PrestaShop en una infraestructura de Single SignOn. En una próxima entrega se explicará como usar este módulo junto con otros elementos para construir la infraestructura de Inicio de Sesión Único completa.

¿Qué es OAuth?

OAuth es un protocolo abierto que permite asociar una autorización a un token, de forma que se permitan realizar peticiones autorizadas en nombre de un usuario determinado, sin necesidad de exponer las credenciales de dicho usuario (su nombre de usuario y contraseña).

En esencia OAuth permite a un usuario del sitio A compartir su información en el sitio A (proveedor de servicio) con el sitio B (llamado consumidor) sin compartir toda su identidad.

La versión 2 de este protocolo se soporta bajo conexiones encriptadas TLS/SSL mientras que la versión 1 puede usarse sobre conexiones no seguras y delega la seguridad a un mecanismo mas complicado de firma digital. Ambas versiones no son compatibles.

Algunos términos importantes sobre OAuth:

  • Resource Owner – El usuario.
  • Resource Server – El servidor que posee los usuarios.
  • Client – La aplicación que se conecta vía OAuth (nuestra tienda PrestaShop).
  • Authorization Server – El servidor que concede las autorizaciones. Típicamente el mismo que posee los usuarios.
  • Authorization Code – Un código temporal que se crea para generar un token de acceso (access token).
  • Access Token – Un token (una secuencia larga de números y letras) que representa la autorización que ha dado un usuario para que el cliente pueda acceder a sus datos.
  • Scope – Representa un conjunto de datos de un usuario. Un access token permite a un cliente acceder a uno o varios scopes del usuario. Por ejemplo, si piensas en una red social, un scope serían los datos básicos del usuario (nombre, apellidos, …) y otro sería sus contactos (seguidores, amigos, …) y otro distinto sus fotografías o sus likes.

Cuando el usuario del sitio A concede la autorización al sitio B, suele indicar para cuales de los scopes que se han definido se concede esta autorización de acceso. El access token es la forma de que el sitio B haga valer ante A esta autorización cuando solicita que se le facilite alguno de los scopes del usuario.

Al flujo concreto que se utiliza entre el cliente y el servidor para obtener una token de acceso, se denomina Grant Type. Hay varios:

  • Autorization Code – Es el más habitual y el que implementa el módulo PrestaShop. Consta de dos pasos, primero se obtiene un authorization code que mas adelante se intercambia por un access token.
  • Implicit – Se usa en aplicaciones JavaScript y en aplicaciones móviles en las que no se pueden almacenar de forma segura unas credenciales para el cliente.
  • User Credentials – En este caso la propia aplicación cliente va a facilitar las credenciales del usuario que generalmente se obtendrán de un formulario de inicio de sesión en la aplicación cliente.
  • Client Credentials – Esta es una autorización que en lugar de estar asociada a un usuario está asociada a la aplicación cliente. Las subsiguientes solicitudes del cliente usando el access token se refieren a los permisos que desde el servidor se hayan concedido a la aplicación cliente.
  • Refresh Token – El access token caduca pasado un tiempo. Pero cuando se facilita este token de acceso se facilita también un refresh token, que nos permite generar un nuevo access token una vez que el primero haya caducado.

Para que OAuth funcione, en el Servidor de Autorización se debe crear y configurar la aplicación cliente. La configuración típicamente incluye lo siguiente:

  • Un nombre descriptivo del cliente.
  • Las credenciales del cliente:
    • Client ID
    • Client Secret
  • Los Grant Types permitidos para este cliente.
  • Los scopes permitidos para este cliente (se refiere a los que pueden llegar a solicitar, pero será el usuario el que determine a cuáles da acceso en su caso en particular).
  • La URI de redirección, que se usará para redirigir el flujo a la aplicación cliente durante un proceso de autorización. Para entenderlo debes tener en cuenta que la validación de las credenciales del usuario, incluso el formulario en el que se solicitan las credenciales y el posible proceso de validación de identidad en dos pasos, ocurren fuera de la aplicación cliente. Por tanto, cuando toda esta parte del proceso se completa, el servidor de autorizaciones invoca de nuevo a la aplicación cliente para continuar con el intercambio de tokens. Esta URI es facilitada por la aplicación cliente, aunque típicamente es https://my-client-application.com/?auth=sso

Deberás configurar el cliente en el Servidor de Autorización antes de poder configurar la parte cliente como tal. Fundamentalmente por que vas a necesitar obtener tus credenciales de acceso de cliente (Client ID + Client Secret).

Usando OAuth en una solución de Single SignOn

Cuando se trata de una solución de Single SignOn (inicio de sesión único), lo que vamos a pedir a la parte servidora que haga será:

  • Contener la base de datos centralizada de usuarios, con sus credenciales y al menos algunos datos básicos.
  • Para una operación de SignOn, validar las credenciales del cliente (biometría, usuario y contraseña, validación de identidad en dos pasos, …) y en el caso de que sean válidas devolver a la parte cliente la información básica del usuario.
  • En subsiguientes peticiones de inicio de sesión en el mismo cliente o en cualquier otro federado, la parte servidora evitará solicitar nuevamente las credenciales al usuario y devolverá simplemente los datos del usuario. Todo esto ocurre dentro de un inicio de sesión federado, que en algún momento caducará y volverá a requerir que el usuario presente sus credenciales.

Esta parte servidoras se va a denominar Servidor de Identidades. Al conjunto de webs y aplicaciones que validan la identidad de sus usuarios a través de un mismo Servidor de Identidades se la va a denominar Federación, y también se dirá que el usuario tiene una Identidad Federada.

Básicamente los clientes de esta infraestructura SSO lo que van a pedir al Servidor de Identidades es «Dame la identidad de la persona que ha iniciado sesión», y crearán internamente un usuario a partir de la identidad facilitada.

La «identidad» que facilita el servidor constará de los siguientes elementos:

  • Como mínimo de un identificador único (un ID, un nombre de usuario, …).
  • Datos básicos del usuario, siendo los mas básicos:
    • El nombre
    • El/los apellido(s)
    • Una dirección de correo electrónico
  • Opcionalmente una lista de roles que el usuario tiene dentro de la federación. Los roles generalmente representan los permisos que se le conceden a un usuario y pueden o no ser relevantes para un cliente determinado (ej. el role de «gestor de contabilidad» solo tendrá sentido para las aplicaciones de contabilidad).
La robustez de una infraestructura de autenticación depende en último término del eslabón mas débil de la cadena: la capacidad del usuario para no revelar sus credenciales.

Para una solución planteada en estos términos, OAuth será la tecnología que nos permitirá realizar esa petición de «Dame la identidad de la persona que ha iniciado sesión». Para ello se usará un Grant Type de tipo Authorization Code, que delega completamente en el servidor la parte de validación de las credenciales del usuario.

El cliente debe solicitar acceso a un Scope determinado de los datos del usuario. En este caso vamos solicitar acceso al profile del usuario, que asumimos que deberá contener al menos el identificador del usuario y sus datos básicos (y opcionalmente los roles).

Módulo oauthsso

Si has seguido el artículo hasta aquí, es fácil describir lo que hace el módulo oauthsso: implementa la parte cliente del protocolo OAuth 2.0 para comunicarse con un servidor central de identidades, permitiendo el inicio de sesión en la tienda PrestaShop a partir de la identidad federada facilitada por el servidor.

Este tipo de validación se usa únicamente para los clientes de la tienda (no para los empleados) y es perfectamente compatible con el inicio de sesión tradicional de PrestaShop. No obstante, al implementar una solución de inicio de sesión único a nivel corporativo, lo habitual será que solo se permita el acceso a través de un usuario definido en el servidor central.

La instalación del módulo se hace como cualquier otro módulo de PrestaShop. Descárgate aquí la última release estable del módulo, o clona el repositorio de GitHub.

A continuación te voy a explicar cómo configurarlo y así descubrirás las diferentes capacidades que te ofrece este módulo PrestaShop gratuito.

Configurar el Servidor de Identidades

La configuración mínima que hay que hacer de este módulo se refiere al servidor de identidades OAuth 2.0.

  • Nombre del Servidor OAuth: Este es el nombre de dominio completo (FQDN) del Servidor de Identidades.
  • ID del cliente (Client ID): Parte de las credenciales que se habrán creado en el Servidor de Identidades al configurar allí nuestro cliente.
  • Secreto del cliente (Client Secret): La otra parte de las credenciales.
  • Nombre del Proveedor SSO: Este es el texto que aparecerá en el botón de Inicio de Sesión Único y en algunos correos como identificación del proveedor de Inicio de Sesión Único.

También verás en la parte superior de este bloque, que se muestra la Redirect URI. La debes configurar en el Servidor de Identidades para que sea capaz de invocar de vuelta al módulo durante los procesos de autorización.

El botón Verificar la configuración de OAuth te permite probar la conexión con tu servidor. Si aparece el mensaje «Los ajustes son correctos – ¡No olvides salvar los cambios!», todo estará configurado de forma correcta. En caso contrario el mensaje de error te orientará sobre lo que va mal.

Configurar la conexión con la API OAuth

La configuración ideal de la API consiste en usar CURL y comunicarse a través de una conexión cifrada por el puerto 443. No obstante el módulo admite otras opciones.

El botón «Autodetectar parámetros de conexión con la API» irá probando las combinaciones de la mas idónea a la menos segura, mostrándote cual es la mejor opción que funciona en tu caso. Te recomiendo que uses el botón y que utilices la configuración sugerida.

Configurar los hooks

El módulo va a poder mostrar un botón (widget) que se encargará de disparar el proceso de inicio de sesión. Este botón se va a mostrar en uno o varios sitios de tu tienda y para ello se ofrecen una serie de hooks de Prestashop en lo que poder enganchar el módulo:

  • Página de inicio de sesión
  • Página de registro
  • Menú de navegación
  • Columna izquierda
  • Columna derecha
  • Columna derecha de la página de producto

Puedes habilitar o deshabilitar cada uno de estos hooks. También puedes usar un hook personalizado e incluirlo en las plantillas Smarty de tu tienda, con lo que potencialmente puedes incluir el widget de inicio de sesión único en todos los sitios de la tienda que desees.

{$HOOK_OASSO_CUSTOM nofilter}

Personalizar la tienda

Para poder integrarse de forma adecuada con el diseño visual de tu tema, el módulo oauthsso te permite añadir código CSS y JavaScript personalizado.

El módulo no encola ninguna librería de estilos propia por lo que si el módulo se muestra con un aspecto pobre o discordante, puedes añadir reglas CSS para conseguir un aspecto adecuado.

Te sugiero incluir al menos dos reglas como estas (adaptadas a tu estética):

.block.oauth_sso_block_column {
    box-shadow: 2px 2px 11px 0 rgba(0,0,0,.1);
    background: #fff;
    padding: 1.5625rem 1.25rem;
    margin-bottom: 1.5625rem;
}

.oauthsso-wrapper {
    max-width: 600px;
    margin: 1em auto;
    padding: 1em;
    box-shadow: 2px 2px 11px 0 rgba(0,0,0,.1);
}

Algunos apuntes a la hora de personalizar el widget de Inicio de Sesión Único:

  • Todos los widgets de OAuth 2.0 Cliente de Inicio de Sesión Único tienen la clase ‘oauth_sso_block’
  • Widget en Inicio de Sesión (ID y clase): ‘oauth_sso_customer_login_form’
  • Widget en Crear una Cuenta (ID y clase): ‘oauth_sso_customer_account_form’
  • Widget integrado a medida (ID y clase): ‘oauth_sso_custom’
  • Widget en columna izquierda, clase: ‘oauth_sso_block_column’ ID: ‘oauth_sso_block_left_column’
  • Widget en columna derecha, clase: ‘oauth_sso_block_column’ ID: ‘oauth_sso_block_right_column’
  • Widget en columna derecha (producto), clase: ‘oauth_sso_block_column’ ID: ‘oauth_sso_block_right_column_product’
  • Envoltorio del botón de Inicio de Sesión Único (ID y clase): ‘oauth_sso_provider’
  • Botón de Inicio de Sesión Único (ID y clase): ‘oauth_sso_button’

El código JavaScript personalizado te permite realizar cualquier otra acción que no tenga que ver con el aspecto visual. Por ejemplo, si muestras el botón de Single SignOn en la página de inicio de sesión y quieres deshabilitar el formulario estándar de inicio de sesión de Prestashop, puedes hacerlo a través de JavaScript.

jQuery("#login-form").hide();

Configurar el mapeo de roles

Esta funcionalidad depende mucho de las capacidades que tenga tu Servidor de Identidades y no es una funcionalidad estándar ni tiene nada que ver con OAuth.

Si tu Servidor de Identidades es capaz de enviar una lista con los roles del usuario, la funcionalidad de mapeo de roles te va a permitir asociar los roles a grupos de clientes, que es el concepto mas parecido en PrestaShop a la hora de implementar roles.

En este ejemplo el grupo de clientes Premium tiene unas condiciones de envío mejoradas y el grupo Private Shopper da acceso a una parte del catálogo que no está disponible de forma pública.

Debes habilitar el mapeo de roles si tu servidor de identidad facilita una lista de roles para un scope de tipo profile (o configurar dicho scope para que se incluye esta información, si tal cosa es posible).

A continuación debes indicar el nombre de la propiedad en la que el Servidor de Identidades va a indicar esta lista de roles (no existe un estándar a este respecto).

Luego debes indicar cómo se debe interpretar el contenido de esta propiedad. Dado que los datos que el servidor envía vienen en formato JSON, se soportan los siguientes formatos:

  • Un nombre de rol individual.
{
	...
	"role": "premium_delivery"
	...
}
  • Una lista de nombres de roles separados por comas.
{
	...
	"user_roles_names": "contributor, myshop_private_shopper, premium_delivery, external"
	...
}
  • Un arreglo de roles, donde el nombre del rol es la clave del arreglo.
{
	...
	"user_roles": {
		"contributor": true,
		"myshop_private_shopper": true,
		"premium_delivery": true,
		"external": true
	}
	...
}
  • Un arreglo de roles, donde el nombre del rol es el valor del arreglo.
{
	...
	"user_roles": [
		"contributor",
		"myshop_private_shopper",
		"premium_delivery",
		"external"
	]
	...
}

A continuación habrá que indicar los mapeos o correspondencia entre los nombres de los roles y los grupos de PrestaShop en nuestra tienda.

No es necesario mapear todos los roles. Solo aquellos que tengan significado en nuestra tienda. Por otro lado un mismo role puede mapearse con varios grupos de clientes en nuestra tienda.

El mapeo puede no solo afectar a la pertenencia del cliente al grupo de clientes, sino que además puede fijarse como grupo predeterminado para dicho cliente. Si varios mapeos establecen fijan el grupo como predeterminado, se quedará fijado al último valor posible de acuerdo al orden en el que se listan los mapeos.

Los roles de un usuario se mapean a grupos de clientes de la tienda la primera vez que se crea el cliente y cada vez que inicia sesión. El módulo nos permite elegir si queremos que además de añadir nuevos roles cuando sea necesario, queremos limpiar los roles pre-existentes. Si lo habilitamos, tras iniciar sesión el usuario solo pertenecerá a aquellos grupos de clientes que se hayan podido mapear a partir de la lista de roles enviadas por el Servidor de Identidades. A la hora de configurar los mapeos ten en cuenta que PrestaShop suele asumir que cualquier cliente pertenecerá al menos al grupo Invitado o Cliente.

Habilitar las notificaciones

El módulo oauthsso te permite enviar notificaciones por correo electrónico cuando se crea un nuevo cliente en la tienda, como consecuencia de realizar un inicio de sesión de tipo Single SignOn por primera vez con ese usuario.

Las notificaciones se pueden enviar a los administradores de la tienda y/o a los propios clientes.

La notificación al cliente incluye la contraseña aleatoria que se ha creado para dicho cliente, lo que le permitiría volver a iniciar sesión por el mecanismo estándar de PrestaShop. Si no se permite el inicio de sesión tradicional de PrestaShop debes deshabilitar esta notificación o personalizar la plantilla de correo.

Enlazado de cuentas

Si instalas el módulo oauthsso en una tienda en marcha, ya existirá una base de datos local de clientes con sus direcciones, histórico de pedidos y demás.

El enlazado de cuentas te permite que la próxima vez que un cliente de la tienda inicie su sesión a través del mecanismo de inicio de sesión único, el cliente de PrestaShop que se le asigne sea el mismo que tenía antes de instalar el módulo, y por tanto conserve su historial de pedidos, direcciones, …

Si deshabilitas el enlazado de cuentas nunca se va a asociar un cliente identificado vía SSO a una cuenta de cliente pre-existente. Esto puede causar un conflicto si los clientes pre-existentes también están incluidos en el Servidor de Identidades, por que PrestaShop identifica al cliente por su dirección de correo electrónico.

Validación de los datos del usuario

La última opción configurable del módulo se refiere a qué se debe hacer antes de crear una nueva cuenta de cliente en PrestaShop. Los datos mínimos que PrestaShop necesita para crear una cuenta de cliente son: nombre, apellidos y dirección de correo electrónico.

Estos datos pueden o no estar presentes en los datos que nos envíe el servidor de identidades.

Las opciones que se ofrecen son:

  • Hacer que el usuario siempre valide sus datos cuando se registra a través del Inicio de Sesión Único.
  • Preguntar solo por los campos no presentes.
  • No preguntar nunca. Usar valores por defecto para los datos no presentes.

En el primer caso, previo al registro, siempre se nos mostrarán los datos enviados desde el Servidor de Identidades, y podremos validarlos o modificarlos.

En el segundo caso solo se nos solicitará validar los datos en el caso de que al menos uno de los tres sea desconocido. Si todos los datos están completos la cuenta de cliente en PrestaShop se creará sin mas interacción.

Con la tercera opción los datos que no conozcamos se rellenarán con valores por defecto. Usar esta opción puede ser arriesgado porque la dirección de correo que le asignemos al cliente será una dirección de correo inexistente.

Por supuesto, cualquier modificación que hagas en la página de ajustes, no olvides de pulsar el botón Guardar Ajustes para que los cambios tomen efecto.

Traducciones

Siguiendo las buenas prácticas de programación de PrestaShop la interfaz de usuario del módulo se ha creado en inglés y como habrás podido comprobar por las capturas de pantalla de este artículo, también está disponible la traducción al castellano.

Si necesitas traducir el módulo a otro idioma puedes usar las herramientas habituales de traducción de PrestaShop. Si creas una traducción del módulo en otro idioma, por favor envíamela para incluirla en el repositorio y ponerla a disposición de futuros usuarios.

NOTA: La versión 1.7.7.1 de PrestaShop no dispone de herramientas administrativas que permitan la traducción del Asunto para los correos personalizados que genere un módulo. No obstante es posible generar estas traducciones a base de modificar manualmente algunos de los archivos de código fuente pertenecientes al tema de tu tienda. Si estas familiarizado con la realización de estos cambios a nivel de código fuente, revisa el archivo /translations/es-lang.php que contiene instrucciones y código de ejemplo para llevar a cabo esta traducción.

Agradecimientos

Este módulo se desarrolló como parte de un proyecto de creación de una infraestructura de Single SignOn dentro de PLC Madrid. No encontramos ningún módulo PrestaShop que realizase la función requerida y se optó por crear uno, partiendo de otro módulo PrestaShop (Social Login by OneAll) que está orientado al inicio de sesión con tus perfiles en redes sociales.

El módulo se desarrolló bajo el auspicio de PLC Madrid, pero ha sido amablemente cedido a La Comunidad, por lo que está permitido que cualquiera pueda usarlo, ampliarlo y mejorarlo sin necesidad de desembolsar ningún royalty. El módulo se entrega con licencia GPL 2.0.

Agradezco por tanto a OneAll por la parte de su infraestructura que desarrollan como OpenSource, que ha sido el germen del presente módulo, y a PLC Madrid por ceder el resultado final a La Comunidad.

Si quieres contribuir, este es el repositorio de GitHub del módulo.