Autenticación entre servicios
Además de autenticar las solicitudes de los usuarios finales, puede que quieras autenticar los servicios (usuarios no humanos) que envían solicitudes a tu API. En esta página se explica cómo usar cuentas de servicio para proporcionar autenticación a personas o servicios.
Información general
Para identificar un servicio que envía solicitudes a tu API, debes usar una cuenta de servicio. El servicio que llama usa la clave privada de la cuenta de servicio para firmar un JSON Web Token (JWT) seguro y envía el JWT firmado en la solicitud a tu API.
Para implementar la autenticación con cuenta de servicio en tu API y en el servicio de llamada, sigue estos pasos:
- Crea una cuenta de servicio y una clave para que las use el servicio de llamada.
- Añade compatibilidad con la autenticación en la configuración de la API de tu servicio API Gateway.
Añade código al servicio de llamadas que haga lo siguiente:
- Crea un JWT y lo firma con la clave privada de la cuenta de servicio.
- Envía el JWT firmado en una solicitud a la API.
API Gateway valida que las reclamaciones del JWT coincidan con la configuración de tu API antes de reenviar la solicitud a tu API. API Gateway no comprueba los permisos de Cloud Identity que hayas concedido en la cuenta de servicio.
Requisitos previos
En esta página se da por hecho que ya has hecho lo siguiente:
Crear una cuenta de servicio con una clave
Necesitas una cuenta de servicio con un archivo de clave privada que el servicio de llamada utilice para firmar el JWT. Si tienes más de un servicio que envía solicitudes a tu API, puedes crear una cuenta de servicio que represente a todos los servicios que hacen llamadas. Si necesitas diferenciar entre los servicios (por ejemplo, si tienen permisos diferentes), puedes crear una cuenta de servicio y una clave para cada servicio de llamada.
En esta sección se muestra cómo usar la consola de Google Cloud y la herramienta de línea de comandos gcloud
para crear la cuenta de servicio y el archivo de clave privada, así como para
asignar a la cuenta de servicio el rol
Creador de tokens de cuenta de servicio. Para obtener información sobre cómo usar una API para llevar a cabo esta tarea, consulta el artículo Crear y gestionar cuentas de servicio.
Para crear una cuenta de servicio con una clave, sigue estos pasos:
Google Cloud consola
Crea una cuenta de servicio:
En la Google Cloud consola, ve a Crear cuenta de servicio.
Selecciona un proyecto.
En el campo Nombre de cuenta de servicio, escribe un nombre. La consola rellena el campo ID de cuenta de servicio en función de este nombre.Google Cloud
Opcional: En el campo Descripción de la cuenta de servicio, escribe una descripción.
Haz clic en Crear.
Haz clic en el campo Selecciona un rol.
En Todos los roles, selecciona Cuentas de servicio > Creador de tokens de cuenta de servicio.
Haz clic en Continuar.
Haz clic en Hecho para terminar de crear la cuenta de servicio.
No cierres la ventana del navegador. Lo usarás en el siguiente procedimiento.
Crea una clave de cuenta de servicio:
- En la Google Cloud consola, haz clic en la dirección de correo de la cuenta de servicio que has creado.
- Haz clic en Teclas.
- Haz clic en Añadir clave y, a continuación, en Crear clave.
- Haz clic en Crear. Se descargará un archivo de clave JSON en tu ordenador.
- Haz clic en Cerrar.
gcloud
Puedes ejecutar los siguientes comandos mediante la CLI de Google Cloud en tu máquina local o en Cloud Shell.
Define la cuenta predeterminada de
gcloud
. Si tienes más de una cuenta, asegúrate de elegir la cuenta del Google Cloud proyecto que quieras usar.gcloud auth login
Muestra los IDs de los proyectos de Google Cloud .
gcloud projects list
Define el proyecto predeterminado. Sustituye
PROJECT_ID
por el ID del proyecto que quieras usar. Google Cloudgcloud config set project PROJECT_ID
Crea una cuenta de servicio. Sustituye
SA_NAME
ySA_DISPLAY_NAME
por el nombre y el nombre visible que quieras usar.gcloud iam service-accounts create SA_NAME \ --display-name "SA_DISPLAY_NAME"
Se muestra la dirección de correo de la cuenta de servicio que acabas de crear.
gcloud iam service-accounts list
Añade el rol Creador de tokens de cuenta de servicio. Sustituye
SA_EMAIL_ADDRESS
por la dirección de correo de la cuenta de servicio.gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:SA_EMAIL_ADDRESS \ --role roles/iam.serviceAccountTokenCreator
Crea un archivo de clave de cuenta de servicio en el directorio de trabajo actual. Sustituye
FILE_NAME
por el nombre que quieras usar para el archivo de claves. De forma predeterminada, el comandogcloud
crea un archivo JSON.gcloud iam service-accounts keys create FILE_NAME.json \ --iam-account SA_EMAIL_ADDRESS
Consulta la referencia de gcloud
para obtener más información sobre los comandos anteriores.
Para obtener información sobre cómo proteger la clave privada, consulta las prácticas recomendadas para gestionar las credenciales.
Configurar tu API para que admita la autenticación
Cuando crea una configuración de API para su pasarela, especifica una cuenta de servicio que la pasarela usa para interactuar con otros servicios. Para habilitar la autenticación de cuentas de servicio en los servicios que llaman a tu pasarela, modifica el objeto de requisito de seguridad y el objeto de definiciones de seguridad en la configuración de tu API. Si sigues los pasos que se indican a continuación, API Gateway podrá validar las reclamaciones del JWT firmado que usan los servicios que llaman.
Añada la cuenta de servicio como emisor en la configuración de la API.
securityDefinitions: DEFINITION_NAME: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "SA_EMAIL_ADDRESS" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SA_EMAIL_ADDRESS"
- Sustituye
DEFINITION_NAME
por una cadena que identifique esta definición de seguridad. Puedes sustituirlo por el nombre de la cuenta de servicio o por un nombre que identifique el servicio que hace la llamada. - Sustituye
SA_EMAIL_ADDRESS
por la dirección de correo de la cuenta de servicio. - Puedes definir varias definiciones de seguridad en la configuración de tu API, pero cada una debe tener un
x-google-issuer
diferente. Si has creado cuentas de servicio independientes para cada servicio de llamada, puedes crear una definición de seguridad para cada cuenta de servicio. Por ejemplo:
securityDefinitions: service-1: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-1@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-1@example-project-12345.iam.gserviceaccount.com" service-2: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-2@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-2@example-project-12345.iam.gserviceaccount.com"
- Sustituye
Si quiere, puede añadir
x-google-audiences
a la secciónsecurityDefinitions
. Si no añadex-google-audiences
, API Gateway requiere que la reclamación"aud"
(audiencia) del JWT tenga el formatohttps://SERVICE_NAME
, donde SERVICE_NAME es el nombre de su servicio de API Gateway, que ha configurado en el campohost
de su documento OpenAPI.Añada una sección
security
en el nivel superior del archivo (sin sangría ni anidación) para aplicarla a toda la API, o en el nivel del método para aplicarla a un método específico. Si usas seccionessecurity
tanto a nivel de API como a nivel de método, los ajustes a nivel de método anulan los ajustes a nivel de API.security: - DEFINITION_NAME: []
- Sustituye
DEFINITION_NAME
por el nombre que has usado en la secciónsecurityDefinitions
. Si tienes más de una definición en la sección
securityDefinitions
, añádelas en la secciónsecurity
. Por ejemplo:security: - service-1: [] - service-2: []
- Sustituye
Implementa la configuración de API actualizada.
Antes de reenviar una solicitud a tu API, API Gateway verifica lo siguiente:
- La firma del JWT mediante la clave pública, que se encuentra en el URI especificado en el campo
x-google-jwks_uri
de la configuración de la API. - Que la reclamación
"iss"
(emisor) del JWT coincida con el valor especificado en el campox-google-issuer
. - Que la reclamación
"aud"
(audiencia) del JWT contenga el nombre de tu servicio de API Gateway o coincida con uno de los valores que hayas especificado en el campox-google-audiences
. - Que el token no haya caducado mediante la reclamación
"exp"
(hora de vencimiento).
Para obtener más información sobre x-google-issuer
, x-google-jwks_uri
y x-google-audiences
, consulta Extensiones de OpenAPI.
Realizar una solicitud autenticada a una API de API Gateway
Para hacer una solicitud autenticada, el servicio que llama envía un JWT firmado por la cuenta de servicio que has especificado en la configuración de la API. El servicio de llamadas debe cumplir los siguientes requisitos:
- Crea un JWT y fírmalo con la clave privada de la cuenta de servicio.
- Envía el JWT firmado en una solicitud a la API.
El siguiente código de ejemplo muestra este proceso para algunos idiomas. Para hacer una solicitud autenticada en otros idiomas, consulta jwt.io para ver una lista de bibliotecas compatibles.
-
En el servicio de llamada, añade la siguiente función y pásale los siguientes parámetros:
Java -
saKeyfile
: ruta completa al archivo de clave privada de la cuenta de servicio. -
saEmail
: la dirección de correo de la cuenta de servicio. -
audience
: Si has añadido el campox-google-audiences
a tu configuración de la API, asigna aaudience
uno de los valores que hayas especificado parax-google-audiences
. De lo contrario, asigna el valorhttps://SERVICE_NAME
aaudience
, dondeSERVICE_NAME
es el nombre del servicio de API Gateway. -
expiryLength
: tiempo de vencimiento del JWT, en segundos.
Python -
sa_keyfile
: ruta completa al archivo de clave privada de la cuenta de servicio. -
sa_email
: la dirección de correo de la cuenta de servicio. -
audience
: si has añadido el campox-google-audiences
a tu configuración de la API, asigna aaudience
uno de los valores que hayas especificado parax-google-audiences
. De lo contrario, asigna el valorhttps://SERVICE_NAME
aaudience
, dondeSERVICE_NAME
es el nombre del servicio de API Gateway. -
expiry_length
: tiempo de vencimiento del JWT, en segundos.
Ir -
saKeyfile
: ruta completa al archivo de clave privada de la cuenta de servicio. -
saEmail
: la dirección de correo de la cuenta de servicio. -
audience
: si has añadido el campox-google-audiences
a tu configuración de la API, asigna aaudience
uno de los valores que hayas especificado parax-google-audiences
. De lo contrario, asigna el valorhttps://SERVICE_NAME
aaudience
, dondeSERVICE_NAME
es el nombre del servicio de API Gateway. -
expiryLength
: tiempo de vencimiento del JWT, en segundos.
La función crea un JWT, lo firma con el archivo de clave privada y devuelve el JWT firmado.
Java Python Ir -
-
En el servicio de llamada, añade la siguiente función para enviar el JWT firmado en el encabezado
Authorization: Bearer
de la solicitud a la API:Java Python Ir
Cuando envías una solicitud mediante un JWT, por motivos de seguridad, te recomendamos que incluyas el token de autenticación en el encabezado Authorization: Bearer
. Por ejemplo:
curl --request POST \ --header "Authorization: Bearer ${TOKEN}" \ "${GATEWAY_URL}/echo"
donde GATEWAY_URL
y TOKEN
son variables de entorno que contienen la URL de la pasarela implementada y el token de autenticación, respectivamente.
Recibir resultados autenticados en tu API
API Gateway suele reenviar todos los encabezados que recibe. Sin embargo, anula el encabezado Authorization
original cuando la dirección del backend se especifica mediante x-google-backend
en la configuración de la API.
API Gateway enviará el resultado de la autenticación en el X-Apigateway-Api-Userinfo
a la API de backend. Se recomienda usar este encabezado en lugar del encabezado Authorization
original. Este encabezado está codificado en base64url
y contiene la carga útil del JWT.