Cuando una app que se ejecuta en el entorno de ejecución de Python 2 envía una solicitud a otra app de App Engine, puede usar la API de App Identity de App Engine para confirmar su identidad. La app que recibe la solicitud puede usar esta identidad para determinar si debe procesar la solicitud.
Si tus apps de Python 3 necesitan confirmar su identidad cuando envían solicitudes a otras apps de App Engine, puedes usar tokens de ID de OpenID Connect (OIDC) que sean emitidos y decodificados por las API de OAuth 2.0 de Google.
A continuación, se muestra una descripción general del uso de tokens de ID de OIDC para confirmar y verificar la identidad:
- Una app de App Engine llamada “App A” recupera un token de ID desde el entorno de ejecución de Google Cloud.
- La App A agrega este token a un encabezado de solicitud justo antes de enviar la solicitud a la App B, que es otra aplicación de App Engine.
- La App B usa las API de OAuth 2.0 de Google para verificar la carga útil del token. La carga útil decodificada contiene la identidad verificada de la App A en el formato de la dirección de correo electrónico de la cuenta de servicio predeterminada de la App A.
- La App B compara la identidad en la carga útil con una lista de identidades a las que puede responder. Si la solicitud provino de una app permitida, la App B procesa la solicitud y responde.
En esta guía, se describe cómo actualizar las apps de App Engine a fin de usar tokens de ID de OpenID Connect (OIDC) para confirmar la identidad y cómo actualizar las otras apps de App Engine con el fin de usar tokens de ID destinados a verificar la identidad antes de procesar una solicitud.
Diferencias fundamentales entre las API de App Identity y OIDC
Las apps en el entorno de ejecución de Python 2 no necesitan confirmar su identidad de forma explícita. Cuando una app usa las bibliotecas de Python
httplib
,urllib
ourllib2
, o el servicio de recuperación de URL de App Engine a fin de enviar solicitudes salientes, el entorno de ejecución usa ese servicio para realizar la solicitud. Si la solicitud se envía al dominioappspot.com
, la recuperación de URL confirma de forma automática la identidad de la app solicitante mediante la adición del encabezadoX-Appengine-Inbound-Appid
a la solicitud. Ese encabezado contiene el ID de aplicación de la app (también llamado ID del proyecto).Las apps en el entorno de ejecución de Python 3 deben confirmar su identidad de forma explícita mediante la recuperación de un token de ID de OIDC del entorno de ejecución de Google Cloud y su adición al encabezado de la solicitud. Deberás actualizar todo el código que envía solicitudes a otras apps de App Engine para que las solicitudes contengan un token de ID de OIDC.
El encabezado
X-Appengine-Inbound-Appid
en una solicitud contiene el ID del proyecto de la app que envió la solicitud.La carga útil del token de ID de OIDC de Google no identifica directamente el ID del proyecto de la app. En su lugar, el token identifica la cuenta de servicio en la que se ejecuta la app, ya que proporciona la dirección de correo electrónico de esa cuenta de servicio. Deberás agregar código para extraer el nombre de usuario de la carga útil del token.
Si esa cuenta de servicio es la cuenta de servicio predeterminada de App Engine a nivel de app para el proyecto, el ID del proyecto se puede encontrar en la dirección de correo electrónico de la cuenta de servicio. La parte del nombre de usuario de la dirección es la misma que el ID del proyecto. En este caso, el código de tu app receptora puede buscar esto en la lista de ID de proyectos desde los que permitirá solicitudes.
Sin embargo, si la app que realiza la solicitud usa una cuenta de servicio administrada por el usuario en lugar de la cuenta de servicio predeterminada de App Engine, la app que recibe la solicitud solo puede verificar la identidad de esa cuenta de servicio, lo que no necesariamente definirá el ID de proyecto de la app que realiza la solicitud. En ese caso, la app que recibe la solicitud deberá mantener una lista de correos electrónicos de cuentas de servicio permitidos en lugar de una lista de ID de proyecto permitidos.
Las cuotas para las llamadas a la API de recuperación de URL son diferentes de las cuotas de las API de OAuth 2.0 de Google para otorgar tokens. Puedes ver la cantidad máxima de tokens que puedes otorgar por día en la pantalla de consentimiento de OAuth en la consola de Google Cloud. La recuperación de URL, la API de App Identity y las API de OAuth 2.0 de Google no generan cargos de facturación.
Descripción general del proceso de migración
Si deseas migrar las apps de Python para usar las API de OIDC a fin de confirmar y verificar la identidad, haz lo siguiente:
En el caso de las apps que necesitan confirmar su identidad cuando envían solicitudes a otras apps de App Engine, sigue estos pasos:
Espera hasta que la app se ejecute en un entorno de Python 3 para migrar a los tokens de ID.
Si bien es posible usar tokens de ID en el entorno de ejecución de Python 2, los pasos en Python 2 son complejos y solo se necesitan de forma temporal hasta que actualices tu app para que se ejecute en el entorno de ejecución de Python 3.
Una vez que tu app se ejecute en Python 3, actualízala para solicitar un token de ID y agregar el token a un encabezado de solicitud.
En el caso de las apps que deben verificar su identidad antes de procesar una solicitud, haz lo siguiente:
Comienza por actualizar tus apps de Python 2 para admitir los tokens de ID y las identidades de la API de App Identity. Esto permitirá que tus apps verifiquen y procesen solicitudes desde apps de Python 2 que usan la API de App Identity o apps de Python 3 que usan tokens de ID.
Una vez que las apps actualizadas de Python 2 sean estables, mígralas al entorno de ejecución de Python 3. Sigue admitiendo identidades de la API de App Identity y tokens de ID hasta que estés seguro de que las apps ya no necesitan admitir solicitudes de apps heredadas.
Cuando ya no necesites procesar solicitudes de apps heredadas de App Engine, quita el código que verifica las identidades de la API de App Identity.
Después de probar tus apps, implementa la app que procesa las solicitudes primero. Luego, implementa la app de Python 3 actualizada que usa tokens de ID para confirmar su identidad.
Confirma la identidad
Espera a que tu app se ejecute en un entorno de Python 3 y sigue estos pasos para actualizar la app a fin de que confirme su identidad con tokens de ID:
Instala la biblioteca cliente
google-auth
.Agrega código para solicitar un token de ID de las API de OAuth 2.0 de Google y agrégalo a un encabezado de solicitud antes de enviar una solicitud.
Prueba las actualizaciones.
Instala la biblioteca cliente google-auth
para apps de Python 3
Para que la biblioteca cliente google-auth
esté disponible en la app de Python 3, crea un archivo requirements.txt
en la misma carpeta que tu archivo app.yaml
y agrega la siguiente línea:
google-auth
Cuando implementes la app, App Engine descargará todas las dependencias que se definen en el archivo requirements.txt
.
Para el desarrollo local, te recomendamos que instales dependencias en un entorno virtual, como venv.
Agrega código para confirmar la identidad
Busca en tu código y encuentra todas las instancias de envío de solicitudes a otras apps de App Engine. Actualiza esas instancias para hacer lo siguiente antes de enviar la solicitud:
Agrega las siguientes importaciones:
from google.auth.transport import requests as reqs from google.oauth2 import id_token
Usa
google.oauth2.id_token.fetch_id_token(request, audience)
para recuperar un token de ID. Incluye los siguientes parámetros en la llamada de método:request
: Pasa el objeto de solicitud que estás listo para enviar.audience
: Pasa la URL de la app a la que envías la solicitud. Esto vincula el token a la solicitud y evita que otra app lo use.Por motivos de claridad y especificidad, te recomendamos pasar la URL
appspot.com
que App Engine creó para el servicio específico que recibe la solicitud, incluso si usas un dominio personalizado en la app.
En tu objeto de solicitud, establece el siguiente encabezado:
'Authorization': 'ID {}'.format(token)
Por ejemplo:
Prueba actualizaciones para confirmar la identidad
Para ejecutar tu app de forma local y probar si puede enviar tokens de ID de forma correcta, haz lo siguiente:
Sigue estos pasos a fin de que las credenciales de la cuenta de servicio predeterminada de App Engine estén disponibles en tu entorno local (las API de OAuth de Google requieren estas credenciales para generar un token de ID):
Ingresa el siguiente comando de
gcloud
para recuperar la clave de la cuenta de servicio de la cuenta predeterminada de App Engine de tu proyecto:gcloud iam service-accounts keys create ~/key.json --iam-account project-ID@appspot.gserviceaccount.com
Reemplaza project-ID por el ID del proyecto de Google Cloud.
El archivo de claves de la cuenta de servicio se descargará ahora en tu máquina. Puedes mover y cambiar el nombre de este archivo como desees. Asegúrate de almacenar este archivo de forma segura, ya que se puede usar para autenticarse como tu cuenta de servicio. Si pierdes el archivo, o si este se expone a usuarios no autorizados, borra la clave de la cuenta de servicio y crea una nueva.
Ingresa el siguiente comando:
<code>export GOOGLE_APPLICATION_CREDENTIALS=<var>service-account-key</var></code>
Reemplaza service-account-key por el nombre de ruta absoluto del archivo que contiene la clave de la cuenta de servicio que descargaste.
En la misma shell en la que exportaste la variable de entorno
GOOGLE_APPLICATION_CREDENTIALS
, inicia la app de Python.Envía una solicitud desde la app y confirma que se completó con de forma correcta. Si aún no tienes una app que pueda recibir solicitudes y usar tokens de ID para verificar las identidades, haz lo siguiente:
- Descarga la app de muestra “de entrada”.
En el archivo
main.py
de la muestra, agrega el ID del proyecto de Google Cloud aallowed_app_ids
. Por ejemplo:allowed_app_ids = [ '<APP_ID_1>', '<APP_ID_2>', 'my-project-id' ]
Ejecuta la muestra actualizada en el servidor de desarrollo local de Python 2.
Verifica y procesa solicitudes
Si deseas actualizar las apps de Python 2 para que usen tokens de ID o identidades de la API de App Identity antes de procesar las solicitudes, haz lo siguiente:
Instala la biblioteca cliente google-auth.
Actualiza tu código para hacer lo siguiente:
Si la solicitud contiene el encabezado
X-Appengine-Inbound-Appid
, úsalo para verificar la identidad. Las apps que se ejecutan en un entorno de ejecución heredado, como Python 2, contendrán este encabezado.Si la solicitud no contiene el encabezado
X-Appengine-Inbound-Appid
, busca un token de ID de OIDC. Si el token existe, verifica su carga útil y comprueba la identidad del remitente.
Prueba las actualizaciones.
Instala la biblioteca cliente google-auth para las apps de Python 2
A fin de que la biblioteca cliente google-auth
esté disponible para tu app de Python 2, sigue estos pasos:
Crea un archivo
requirements.txt
en la misma carpeta que tu archivoapp.yaml
y agrega la siguiente línea:google-auth==1.19.2
Te recomendamos usar la versión 1.19.2 de la biblioteca cliente de Cloud Logging, ya que admite apps de Python 2.7.
En el archivo
app.yaml
de tu app, especifica la biblioteca SSL en la secciónlibraries
si aún no se especificó:libraries: - name: ssl version: latest
Crea un directorio para almacenar tus bibliotecas de terceros, como
lib/
. Luego, usapip install
para instalar las bibliotecas en el directorio. Por ejemplo:pip install -t lib -r requirements.txt
Crea un archivo
appengine_config.py
en la misma carpeta que el archivoapp.yaml
. Agrega lo siguiente al archivoappengine_config.py
:# appengine_config.py import pkg_resources from google.appengine.ext import vendor # Set path to your libraries folder. path = 'lib' # Add libraries installed in the path folder. vendor.add(path) # Add libraries to pkg_resources working set to find the distribution. pkg_resources.working_set.add_entry(path)
En el archivo
appengine_config.py
del ejemplo anterior, se supone que la carpetalib
se encuentra en el directorio de trabajo actual. Si no puedes garantizar quelib
esté siempre en el directorio de trabajo actual, especifica la ruta completa a la carpetalib
. Por ejemplo:import os path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib')
Para el desarrollo local, recomendamos que instales dependencias en un entorno virtual como virtualenv para Python 2.
Actualiza el código para verificar solicitudes
Busca en tu código y encuentra todas las instancias de obtención del valor del encabezado X-Appengine-Inbound-Appid
. Actualiza esas instancias para realizar las siguientes acciones:
Agrega las siguientes importaciones:
from google.auth.transport import requests as reqs from google.oauth2 import id_token
Si la solicitud entrante no contiene el encabezado
X-Appengine-Inbound-Appid
, busca el encabezadoAuthorization
y recupera su valor.El valor del encabezado tiene el formato “ID: token”.
Usa
google.oauth2.id_token.verify_oauth2_token(token, request, audience)
para verificar y recuperar la carga útil del token decodificado. Incluye los siguientes parámetros en la llamada de método:token
: Pasa el token que extrajiste de la solicitud entrante.request
: Pasa un objetogoogle.auth.transport.Request
nuevo.audience
: Pasa la URL de la app actual (la app que envía la solicitud de verificación). El servidor de autorización de Google comparará esta URL con la URL que se proporcionó cuando se generó el token en un principio. Si las URL no coinciden, el token no se verificará, y el servidor de autorización mostrará un error.
El método
verify_oauth2_token
muestra la carga útil del token decodificado, que contiene varios pares de nombre/valor, incluida la dirección de correo electrónico de la cuenta de servicio predeterminada de la app que generó el token.Extrae el nombre de usuario de la dirección de correo electrónico en la carga útil del token.
El nombre de usuario es el mismo que el ID del proyecto de esa app que envió la solicitud. Este es el mismo valor que se mostró antes en el encabezado
X-Appengine-Inbound-Appid
.Si el nombre de usuario o ID del proyecto está en la lista de los ID del proyecto permitidos, procesa la solicitud.
Por ejemplo:
Prueba actualizaciones para verificar la identidad
Si deseas probar que tu app pueda usar un token de ID o el encabezado X-Appengine-Inbound-Appid
para verificar las solicitudes, ejecuta la app en el servidor de desarrollo local de Python 2 y envía solicitudes desde apps de Python 2 (que usarán la API de App Identity) y desde apps de Python 3 que envían tokens de ID.
Si no actualizaste tus apps para enviar tokens de ID, haz lo siguiente:
Descarga la app de muestra “de solicitud”.
Agrega credenciales de cuenta de servicio a tu entorno local como se describe en Prueba actualizaciones para confirmar apps.
Usa comandos estándar de Python 3 para iniciar la app de muestra de Python 3.
Envía una solicitud desde la app de muestra y confirma que se ejecute de forma correcta.
Implementa tus apps
Cuando estés listo para implementar las apps, debes hacer lo siguiente:
Si las apps se ejecutan sin errores, usa la división del tráfico para aumentar con lentitud el tráfico de las apps actualizadas. Supervisa las apps con atención para detectar cualquier problema antes de enrutar más tráfico a las apps actualizadas.
Usa una cuenta de servicio diferente para confirmar la identidad
Cuando solicitas un token de ID, en la solicitud se usa la identidad de la cuenta de servicio predeterminada de App Engine según la configuración predeterminada. Cuando verifiques el token, la carga útil del token contendrá la dirección de correo electrónico de la cuenta de servicio predeterminada, que se mapea al ID del proyecto de tu app.
La cuenta de servicio predeterminada de App Engine tiene un nivel de permiso muy alto de forma predeterminada. Puede ver y editar todo el proyecto de Google Cloud, por lo que, en la mayoría de los casos, esta cuenta no será la adecuada cuando tu app necesite autenticarse con los servicios de Cloud.
Sin embargo, la cuenta de servicio predeterminada es segura cuando se confirma la identidad de una app porque solo usas el token de ID para verificar la identidad de la app que envió una solicitud. Los permisos reales que se otorgaron a la cuenta de servicio no se consideran ni se necesitan durante este proceso.
Si prefieres usar una cuenta de servicio diferente para las solicitudes de token de ID, haz lo siguiente:
Configura una variable de entorno llamada
GOOGLE_APPLICATION_CREDENTIALS
para la ruta de acceso a un archivo JSON que contiene las credenciales de la cuenta de servicio. Consulta nuestras recomendaciones para almacenar estas credenciales de forma segura.Usa
google.oauth2.id_token.fetch_id_token(request, audience)
para recuperar un token de ID.Cuando verifiques este token, su carga útil contendrá la dirección de correo electrónico de la cuenta de servicio nueva.