Autenticación de usuarios con Identity-Aware Proxy

A menudo, es necesario autenticar a los usuarios de tu aplicación web, lo que suele requerir una programación especial en ella. En el caso de las apps de Google Cloud Platform, puedes transferir esas responsabilidades al servicio Identity-Aware Proxy. Si solamente necesita restringir el acceso a determinados usuarios, no tendrá que realizar cambios en la aplicación. En caso de que la aplicación deba conocer la identidad del usuario (por ejemplo, para mantener las preferencias del usuario del lado del servidor), Identity-Aware Proxy puede hacerlo con un código mínimo de la aplicación.

¿Qué es Identity-Aware Proxy?

Identity-Aware Proxy (IAP) es un servicio de Google Cloud Platform que intercepta las solicitudes web enviadas a su aplicación, autentica mediante el servicio de identidad de Google al usuario que hace la solicitud y solo deja pasar las solicitudes si provienen de un usuario que usted autorice. Además, puede modificar los encabezados de las solicitudes para que incluyan información sobre el usuario autenticado.

En este codelab, aprenderás a crear tu propia aplicación, restringir el acceso a ella y obtener la identidad del usuario de IAP.

Qué compilarás

En este codelab, compilarás una aplicación web mínima con Google App Engine. Luego, explorarás varias maneras de usar Identity-Aware Proxy para restringir el acceso a la aplicación y proporcionarle información de identidad del usuario. Tu app hará lo siguiente:

  • Mostrar una página de bienvenida
  • Acceder a la información de identidad del usuario que brinda IAP
  • Usar la verificación criptográfica para impedir que se falsifique la información de identidad del usuario

Qué aprenderás

  • Cómo escribir e implementar una aplicación simple de App Engine con Python 3.7
  • Cómo habilitar o inhabilitar IAP para restringir el acceso a su aplicación
  • Cómo trasladar la información de identidad del usuario de IAP a su aplicación
  • Cómo verificar de manera criptográfica la información de IAP para protegerse de la falsificación de identidad

Requisitos

  • Un navegador web moderno como Chrome
  • Conocimientos básicos del lenguaje de programación Python

Este codelab se enfoca en IAP y Google App Engine. Los conceptos y los bloques de código no relevantes se pasan por alto y se proporcionan para que simplemente los copie y pegue.

Trabajará en el entorno de la línea de comandos de Cloud Shell. Primero, abre ese entorno y recupera el código de muestra.

Inicie Console y Cloud Shell.

En la parte superior izquierda de la página del lab, haga clic en el botón Abrir Google Console. Deberá acceder con el nombre de usuario y la contraseña que se muestran debajo de ese botón.

Todos los comandos de este codelab se ejecutarán en Cloud Shell para el proyecto que se creó y abrió. Para abrir Cloud Shell, haga clic en el ícono de activar Cloud Shell que se encuentra a la derecha del encabezado de la página de la consola. La mitad inferior de la página le permitirá ingresar y ejecutar comandos.

Los comandos se pueden ejecutar desde tu propia PC, pero primero debes instalar y configurar el software de desarrollo necesario. Cloud Shell ya tiene todas las herramientas de software que necesita.

Descarga el código

En Cloud Shell, haga clic en el área de la línea de comandos para poder escribir los comandos. Recupere el código de GitHub y, luego, cambie a la carpeta del código:

git clone https://github.com/googlecodelabs/user-authentication-with-iap.git
cd iap-codelab

Esta carpeta contiene una subcarpeta por cada paso de este codelab. Deberá cambiar a la carpeta correcta para completar cada paso.

Esta es una aplicación estándar de App Engine escrita en Python 3.7 que simplemente muestra una página de bienvenida. Lo que haremos será implementarla, probarla y usar IAP para restringir el acceso a ella.

Revise el código de la aplicación

Cambia de la carpeta principal del proyecto a la subcarpeta 1-HelloWorld que contiene el código para este paso.

cd 1-HelloWorld

El código de la aplicación se encuentra en el archivo main.py. Utiliza el framework web Flask para responder las solicitudes web con el contenido de una plantilla. Ese archivo de plantilla está en templates/index.html y, para este paso, contiene solo código HTML sin formato. Un segundo archivo de plantilla contiene un ejemplo básico de una Política de Privacidad en templates/privacy.html.

Hay dos archivos más: requirements.txt enumera todas las bibliotecas de Python no predeterminadas que usa la aplicación, y app.yaml le indica a Google Cloud Platform que esta es una aplicación de Python 3.7 instalada en App Engine.

Puede usar el comando cat para que se muestre cada archivo en la shell, como en el siguiente ejemplo:

cat main.py

Para examinar el código, también puede abrir el editor de código de Cloud Shell. Para ello, haga clic en el ícono de lápiz que se encuentra en la esquina superior derecha de la ventana de Cloud Shell.

No es necesario que modifique ningún archivo para este paso.

Implemente en App Engine

Ahora implemente la aplicación en el entorno estándar de App Engine para Python 3.7

gcloud app deploy

Es posible que debas elegir una región para realizar la implementación. Selecciona una opción cercana a ti que diga que es compatible con el estándar. Cuando se te pregunte si quieres continuar, ingresa Y (sí).

La implementación debería completarse en unos minutos. Verás un mensaje que indica que puedes ver tu aplicación con gcloud app browse. Escriba ese comando. Si no se abre una pestaña nueva en su navegador, haga clic en el vínculo que se muestra para abrirla en una pestaña nueva, o bien cópiela en una pestaña nueva que se abra manualmente si es necesario. Como esta es la primera vez que se ejecuta la aplicación, tardará unos segundos en aparecer mientras se inicia una instancia en la nube. Debería ver la siguiente ventana:

Puede abrir esa misma URL desde cualquier computadora conectada a Internet para ver esa página web. El acceso aún no está restringido.

Restringir el acceso con IAP

En la ventana de Cloud Console, haga clic en el ícono de menú que se encuentra en la esquina superior izquierda de la página, seleccione Seguridad y, luego, Identity-Aware Proxy.

Como es la primera vez que habilitas una opción de autenticación para este proyecto, verás un mensaje en el que se indica que debes configurar tu pantalla de consentimiento de OAuth para poder usar IAP.

Haz clic en el botón CONFIGURAR CONSENTIMIENTO DE PANTALLA. Se abrirá una pestaña nueva para configurar la pantalla de consentimiento.

Complete los espacios en blanco requeridos con los valores correspondientes:

Nombre de la aplicación

Ejemplo de CDA

Correo electrónico de asistencia

su dirección de correo electrónico. Es posible que ya se haya completado.

Dominio autorizado

la parte del nombre de host de la URL de la aplicación, p. ej., iap-example-999999.appspot.com (puedes verla en la barra de direcciones de la página web Hello World que abriste anteriormente). No incluya https:// ni finales / a partir de esa URL.

Debe presionar Intro después de completar este valor.

Vínculo a la página principal de la aplicación

la URL que usó para ver su aplicación

Vínculo a la Política de Privacidad de la aplicación

El vínculo de la página de privacidad en la aplicación, al igual que el vínculo a la página principal con /privacy al final

Haga clic en Guardar. Se le indicará que cree las credenciales. Como no necesitas crear credenciales para este codelab, puedes cerrar esta pestaña del navegador.

Regrese a la página de Identity-Aware Proxy y actualícela. Ahora debería ver una lista de los recursos que puede proteger.

Haz clic en el botón de activación en la columna IAP de la fila de la aplicación de App Engine para activar IAP.

Verá los nombres de dominio que IAP protegerá. Haz clic en ACTIVAR.

Ahora, abre una pestaña del navegador y navega a la URL de la app. Verás una pantalla de Acceder con Google en la que se te solicitará que accedas a la app.

Accede con una cuenta de Google o G Suite. Verá una pantalla en la cual se denegará el acceso.

Logró proteger correctamente su aplicación con IAP, pero aún no le indicó a IAP qué cuentas tienen que poder acceder.

Regrese a la página de Identity-Aware Proxy de Console, seleccione la casilla de verificación junto a la aplicación de App Engine y consulte la barra lateral a la derecha de la página.

Deberá agregar como Miembro cada dirección de correo electrónico (o dirección de Grupos de Google o nombre de dominio de G Suite) que deba poder acceder. Haz clic en AGREGAR MIEMBRO. Ingresa tu dirección de correo electrónico y, luego, elige la función Usuario de apps web protegida con IAP y Cloud IAP para asignarla a esa dirección. Puede ingresar más direcciones o dominios de G Suite de la misma manera.

Haz clic en Guardar. Aparecerá el mensaje "Se actualizó la política" en la parte inferior de la ventana.

Regrese a su aplicación y vuelva a cargar la página. Ahora debería ver su aplicación web, dado que ya accedió con un usuario que autorizó. Sin embargo, es posible que sigas viendo la página “No tienes acceso”, ya que es posible que IAP no vuelva a verificar tu autorización. En ese caso, complete los siguientes pasos:

  • Abre el navegador web en la dirección de la página principal, con /_gcp_iap/clear_login_cookie agregado al final de la URL, como en https://iap-example-999999.appspot.com/_gcp_iap/clear_login_cookie.
  • Ahora verá una nueva pantalla de Acceder con Google en la que ya se mostrará su cuenta. No haga clic en la cuenta, sino en Usar otra cuenta, y vuelva a ingresar sus credenciales.
  • Si completa estos pasos, IAP volverá a verificar su acceso, tras lo cual debería ver la pantalla principal de su aplicación.

Si tiene acceso a otro navegador o puede usar el modo Incógnito en su navegador, y si tiene otra cuenta válida de Gmail o G Suite, puede usar ese navegador para ir hasta la página de su aplicación y acceder con la otra cuenta. Dado que no se autorizó esa cuenta, verá la pantalla “No tienes acceso” en lugar de su aplicación.

Cuando una aplicación está protegida con IAP, puede utilizar la información de identidad que IAP proporciona en los encabezados de la solicitud web que pasa por este servicio. En este paso, la aplicación obtendrá la dirección de correo electrónico del usuario que accedió y un ID persistente de usuario único que el servicio de identidad de Google asignó a ese usuario. Esos datos se mostrarán al usuario en la página de bienvenida.

Este es el paso 2 y el último paso finalizó con Cloud Shell abierto en la carpeta iap-codelab/1-HelloWorld. Cambie a la carpeta de este paso:

cd ~/iap-codelab/2-HelloUser

Implementarla en App Engine

Dado que la implementación tarda unos minutos, comienza por implementarla en el entorno estándar de App Engine para Python 3.7:

gcloud app deploy

Cuando se le pregunte si desea continuar, ingrese Y para responder. La implementación debería completarse después de algunos minutos. Mientras espera, puede examinar los archivos de la aplicación como se describe a continuación.

Cuando la implementación esté lista, verás un mensaje en el que se indica que puedes ver la aplicación con gcloud app browse. Escriba ese comando. Si no se abre una nueva pestaña en su navegador, copie el vínculo que se muestra y ábralo normalmente en otra pestaña. Debería ver una página similar a la siguiente:

Quizás deba esperar algunos minutos para que la nueva versión de su aplicación reemplace a la versión anterior. En caso de ser necesario, actualice la página para ver una página similar a la de arriba.

Examine los archivos de la aplicación

Esta carpeta contiene el mismo conjunto de archivos que en el paso 1, pero se modificaron dos de ellos: main.py y templates/index.html. El programa se modificó para que recupere la información del usuario que IAP proporciona en los encabezados de solicitud, y la plantilla ahora muestra esos datos.

Hay dos líneas en main.py que obtienen los datos de identidad proporcionados por IAP:

user_email = request.headers.get('X-Goog-Authenticated-User-Email')
user_id = request.headers.get('X-Goog-Authenticated-User-ID')

IAP proporciona los encabezados X-Goog-Authenticated-User-, y en los nombres no se distinguen mayúsculas de minúsculas, por lo que pueden escribirse en mayúsculas o en minúsculas si lo prefiere. La instrucción render_template ahora incluye esos valores para que puedan mostrarse:

page = render_template('index.html', email=user_email, id=user_id)

La plantilla index.html puede mostrar esos valores con los nombres entre llaves dobles:

Hello, {{ email }}! Your persistent ID is {{ id }}.

Como puedes observar, los datos proporcionados tienen el prefijo accounts.google.com: para indicar de dónde proviene la información. Su aplicación puede quitar todo hasta los dos puntos (incluidos) a fin de obtener los valores sin procesar, si así lo desea.

Desactive IAP

¿Qué sucederá con esta aplicación si IAP se inhabilita o se omite de alguna manera (por ejemplo, debido a la ejecución de otras aplicaciones en su mismo proyecto en la nube)? Desactive IAP para averiguarlo.

En la ventana de Cloud Console, haga clic en el ícono de menú que se encuentra en la esquina superior izquierda de la página, seleccione Seguridad y, luego, Identity-Aware Proxy. Haga clic en el interruptor de activación de IAP junto a la aplicación de App Engine para desactivar IAP.

Se le advertirá que todos los usuarios podrán acceder a la aplicación.

Actualice la página web de la aplicación. Debería ver la misma página, pero sin información del usuario:

Como la aplicación ahora está desprotegida, un usuario podría enviar una solicitud web que parecería haber pasado por IAP. Por ejemplo, puede ejecutar el siguiente comando curl desde Cloud Shell para hacerlo (reemplace <your-url-here> por la URL correcta de su aplicación):

curl -X GET <your-url-here> -H "X-Goog-Authenticated-User-Email: totally fake email"

La página web se mostrará en la línea de comandos y será similar a la siguiente:

<!doctype html>
<html>
<head>
  <title>IAP Hello User</title>
</head>
<body>
  <h1>Hello World</h1>

  <p>
    Hello, totally fake email! Your persistent ID is None.
  </p>

  <p>
    This is step 2 of the <em>User Authentication with IAP</em>
    codelab.
 </p>

</body>
</html>

La aplicación no tiene manera de saber que se inhabilitó o se omitió IAP. Cuando existe un riesgo potencial, el paso 3 muestra una solución.

Si existe el riesgo de que se desactive o se omita IAP, su aplicación puede realizar una verificación para asegurarse de que la información de identidad que recibe sea válida. Para hacerlo, se utiliza un tercer encabezado de solicitud web que agrega IAP, llamado X-Goog-IAP-JWT-Assertion. El valor del encabezado es un objeto con firma criptográfica que también contiene los datos de identidad del usuario. Su aplicación puede verificar la firma digital y usar los datos proporcionados en este objeto para asegurarse de que los haya proporcionado IAP sin alteraciones.

La verificación de la firma digital requiere varios pasos adicionales, como la recuperación del conjunto más reciente de claves públicas de Google. Puede decidir si su aplicación necesita estos pasos adicionales en función del riesgo de que alguien pueda omitir o desactivar IAP y según la sensibilidad de la aplicación.

Este es el paso 3 y el último paso finalizó con Cloud Shell abierto en la carpeta iap-codelab/2-HelloUser. Cambie a la carpeta de este paso:

cd ~/iap-codelab/3-HelloVerifiedUser

Implemente en App Engine

Implemente la aplicación en el entorno estándar de App Engine para Python 3.7:

gcloud app deploy

Cuando se le pregunte si desea continuar, ingrese Y para responder. La implementación debería completarse después de algunos minutos. Mientras espera, puede examinar los archivos de la aplicación como se describe a continuación.

Cuando la implementación esté lista, verás un mensaje en el que se indica que puedes ver la aplicación con gcloud app browse. Escriba ese comando. Si no se abre una nueva pestaña en su navegador, copie el vínculo que se muestra y ábralo normalmente en otra pestaña.

Recuerde que inhabilitó IAP en el paso 2, por lo que no se le proporcionan datos de IAP a la aplicación. Debería ver una página similar a la siguiente:

Nuevamente, quizás deba esperar algunos minutos para que la versión más nueva esté activa y poder ver la nueva versión de la página.

Dado que IAP está inhabilitado, no hay información de usuario disponible. Ahora, vuelva a activar IAP.

En la ventana de Cloud Console, haga clic en el ícono de menú que se encuentra en la esquina superior izquierda de la página, seleccione Seguridad y, luego, Identity-Aware Proxy. Haga clic en el interruptor de activación de IAP junto a la aplicación de App Engine para volver a activar IAP.

Actualice la página. Debería ser como la siguiente:

Ten en cuenta que la dirección de correo electrónico que proporciona el método verificado no tiene el prefijo accounts.google.com:.

Si se desactiva o se omite IAP, faltarán los datos verificados o estos no serán válidos, dado que no pueden tener una firma válida a menos que los haya creado el titular de las claves privadas de Google.

Examine los archivos de la aplicación

Esta carpeta contiene el mismo conjunto de archivos que en el paso 2, pero se modificaron dos archivos y un archivo nuevo. El archivo nuevo es auth.py, que proporciona un método user() para recuperar y verificar la información de identidad con firma criptográfica. Los archivos modificados son main.py y templates/index.html, que ahora utilizan los resultados de ese método. Los encabezados no verificados como en el paso 2 también se muestran para compararlos.

La nueva funcionalidad se encuentra principalmente en la función user():

def user():
    assertion = request.headers.get('X-Goog-IAP-JWT-Assertion')
    if assertion is None:
        return None, None

    info = jwt.decode(
        assertion,
        keys(),
        algorithms=['ES256'],
        audience=audience()
    )

    return info['email'], info['sub']

assertion son los datos con firma criptográfica que se proporcionan en el encabezado de la solicitud especificado. El código usa una biblioteca para validar y decodificar esos datos. La validación utiliza las claves públicas que proporciona Google para verificar los datos que firma y averiguar para qué público se prepararon los datos (básicamente, el proyecto de Google Cloud que se protege). Las funciones auxiliares keys() y audience() recopilan y muestran esos valores.

El objeto firmado tiene dos datos que necesitamos: la dirección de correo electrónico verificada y el valor de ID único (proporcionado en sub para el suscriptor y el campo estándar).

Aquí termina el paso 3.

Implementó una aplicación web de App Engine. En el paso 1, restringió el acceso a la aplicación para que solo puedan acceder los usuarios que usted elija. En el paso 2, recuperó y mostró la identidad de los usuarios a los que IAP permitió acceder a su aplicación, y vio cómo se podía falsificar la información si se inhabilitaba o se omitía IAP. En el paso 3, verificaste las aserciones con firma criptográfica de la identidad del usuario, que no pueden falsificarse.

Los únicos recursos de Google Cloud Platform que usaste en este codelab son las instancias de App Engine. Cada vez que implementaste la app, se creó una versión nueva que aún existe hasta que se borra. Salga del lab para borrar el proyecto y todos sus recursos.