[PowerBi] Y si hiciéramos Login y RLS en Publish To Web...

El mundo de Power Bi, los contratos, las licencias y las características gratuitas tienen una constante batalla por la reducción de precios. Habiendo participado en licitaciones y pre-ventas entiendo como es la lucha y la búsqueda del menor costo. Todo eso junto con las características gratuitas de power bi me llevaron a pensar en ¿Qué se puede hacer al extremo gratuito?. 

Hace mucho tiempo que este desafío surgió en mi mente. Lo máximo del usuario gratuito es el "Publish To Web", dado que es la forma que tiene de compartir. El problema de siempre es que es público. La sensibilidad de datos. Así llegue a un objetivo que planteaba "¿Como hacer seguros los datos públicos?" y la respuesta es Login

Animate a probarlo en este link. Podes usar usuario LCesar6501@ladataweb.com.ar con password Lo65iaarHi.LC-ol

Contexto

Antes de iniciar es necesario destacar que este práctica y planteo no es 100% seguro. Sin embargo, la práctica que voy a desarrollar tiene un crecimiento lineal en seguridad proporcional a la cantidad de usuarios y el tipo de contraseñas. Mientras más usuarios mayor seguridad. Lo cual puede volverse muy segura y difícil de vulnerar.

image

Esto se debe a que Power Bi no permite el ingreso real de datos ni el bloqueo de la visibilidad por contraseña. Por esto, mientras más combinaciones y más contraseñas tengamos la seguridad será más difícil de superar. Otro influyente es el tipo de contraseñas de los usuarios. Mientras más complejas mayor seguridad.

En este ejemplo vamos a usar una tabla de Customers con 18 mil filas con passwords autogenerados entre 12 y 20 caracteres aleatorios con mayúsculas y minúsculas. El planteo de este escenario es brindar al usuario un acceso a sus datos. En este caso, acceso a sus compras. Veamos el modelo de datos. 

image

El modelo es una sencilla estrella con hechos en ventas y una dimension de clientes que tiene columna usuario y contraseña.

Página Login

Lo primero que necesitamos es una primera y única página visible que será de Login. Para autenticar necesitaremos usuario y contraseña. Power Bi no permite el ingreso de datos pero si el filtro de los mismos. Entonces crearemos dos filtros, uno para usuario y otro para contraseña. Para mejorar la experiencia de usuario vamos a agregar "Buscador" a los Slicer.

Ahora bien tenemos que desactivar la interacción entre ellos dado que sino sería muy fácil saber la contraseña de un usuario. Para mejorar la seguridad, reducimos el espacio de nuestro slicer para que vea un único valor y lo filtramos con TOPN para que no vean más de un valor. Para cerrar la seguridad vamos a setear a los filtros como "Selección única" para que la selección por defecto sea fallida en caso que lleguen a otra página por URL. De esa forma cualquier página estará en blanco hasta que realmente coincida la navegación por contraseña.
NOTA: se podría agregar en el conjunto de datos un usuario y contraseña en blanco para que aparezcan primero o un "-" como utilicé yo.

Una vez separados los filtros necesitamos construir un identificador que nos indique cuando el usuario que seleccionamos coincide con su contraseña que seleccionamos. Tal como un sistema de información, si hacemos coincidir ambos podríamos aceptar que el usuario ingresando datos es quien dice ser. Recién entonces habilitaríamos un botón de navegación. La idea es que al clickear ambos filtros el motor devuelva una única fila con el usuario. El desafío es que el motor devuelva una fila en el contexto al seleccionar exactamente ambos campos correctamente y no con solo el usuario.

Para llegar a ese objetivo vamos a crear las siguientes medidas.

UnicoPassword = COUNTX(ALLSELECTED('Customer'[Password]), 'Customer'[Password])

UnicoUsuario = COUNTX(ALLSELECTED('Customer'[Usuario]), 'Customer'[Usuario])

Las medidas pueden resultar complicadas al inicio pero la idea es sencilla. Cada una de ellas deberá retornar 1 si al filtrar usuario y password obtenemos una única fila. ALLSELECTED nos ayudará a tener todas las filas a menos que reciba una interacción externa como sería el caso de los filtros. Si no tocamos nada, entonces no llegaremos al 1. Si solo tocamos uno de ellos pues vamos a controlar que ambos sean 1.

Nuestra validación la realizará el botón de login. El botón será un botón con acción Page Redirect que estará llevado por la siguiente medida como formato condicional:

Auth = IF (    
     AND( [UnicoPassword] = 1, [UnicoUsuario] = 1 )    
     , "Menu"    , ""

Si ambas medidas son 1 significa que conseguimos una única fila filtrando ambos checks. Por su coincidencia, devolveremos la navegación correspondiente que es "Menú" (nombre de una página de inicio). Si quisiéramos podríamos armar una página de "Usuario y Contraseña no coinciden, vuelva a intentarlo". No me pareció práctico de momento entonces prefiero que no tenga acción.

Navegación

El secreto para continuar la navegación por las páginas está en la "Segmentación de sincronización" (Sync Slicers). Si tenemos todas las demás páginas ocultas y sincronizadas entonces lograríamos un RLS (Seguridad a nivel de filas) puesto que todas las páginas estarían filtradas por el usuario y contraseña correspondiente.

De esa forma tenemos todas las páginas filtradas por el usuario y contraseña.

Para dar más profesionalidad podemos hacer que el botón Login se dirija a un menú como primera instancia. Además, incluir una pequeña visual con el nombre de la persona de la tabla Customer en un cartel "Bienvenido" y una sencilla navegación por el resto de las páginas ocultas.

image

También podemos incorporar un botón "Cerrar Sesión" que redirija a la pantalla de login para una mejor experiencia de usuario. Cabe destacar que nosotros controlamos la navegación, por eso es necesario el botón "atrás" o una navegación personalizada. En este caso el Logo del blog es el botón "atrás".

Recordatorios: Recuerden que mientras más usuarios más seguridad tendremos. Lo recomendado sería que el sistema auto genere las contraseñas para evitar patrones semejantes. También consideren insertar Dummy Data si tienen pocos usuarios con ventas para aumentar la seguridad de lo publicado.

Espero que el post les sea de utilidad y los motive a generar éstas ideas a partir de las funcionalidades de Power Bi. Como siempre pueden revisar el archivo .pbix en mi github para analizar la construcción.

Así logramos construir nuestro sitio Publish to Web con RLS y Login con una aceptable seguridad.