Autenticación entre servicios
Además de autenticar solicitudes de usuarios finales, es posible que desees autenticar servicios (usuarios no humanos) que realizan solicitudes a tu API. En esta página, se explica cómo usar cuentas de servicio para proporcionar autenticación a personas o servicios.
Descripción general
Para identificar un servicio que envía solicitudes a tu API, usas una cuenta de servicio. El servicio de llamadas usa la clave privada de la cuenta de servicio para firmar un token web JSON (JWT) seguro y enviarlo en la solicitud a tu API.
Para implementar la autenticación de cuentas de servicio en tu API y en el servicio de llamadas, completa los pasos siguientes:
- Crea una cuenta de servicio y una clave para que use el servicio de llamadas.
- Agrega compatibilidad con la autenticación en la configuración de la API para tu servicio de API Gateway.
Agrega código al servicio de llamadas que realiza las tareas siguientes:
- 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.
API Gateway valida que las reclamaciones en el JWT coincidan con la configuración en tu configuración de la API antes de reenviar la solicitud a tu API. API Gateway no verifica los permisos de Cloud Identity que hayas otorgado en la cuenta de servicio.
Requisitos previos
En esta página, se supone que ya:
Crea una cuenta de servicio con una clave
Necesitas una cuenta de servicio con un archivo de claves privadas que el servicio de llamadas usa 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 todos los servicios de llamadas. Si necesitas diferenciar entre los servicios (por ejemplo, podrían tener permisos diferentes), puedes crear una cuenta de servicio y una clave para cada servicio de llamadas.
En esta sección, se muestra cómo usar la Google Cloud consola y la gcloud
herramienta de línea de comandos de para crear la cuenta de servicio y el archivo de clave privada, y para
asignar a la cuenta de servicio la
función de Creador de tokens de la cuenta de servicio. Si deseas obtener más información sobre el uso de una API para realizar esta tarea, consulta
Crea y administra cuentas de servicio.
Para crear una cuenta de servicio con una clave, completa los pasos siguientes:
Google Cloud Consola de
Crea una cuenta de servicio:
En la Google Cloud consola, ve a Crear cuenta de servicio.
Selecciona un proyecto
Escribe un nombre en el campo Nombre de cuenta de servicio. La Google Cloud consola de completa el campo ID de cuenta de servicio en función de este nombre.
Opcional: en el campo Descripción de la cuenta de servicio, ingresa una descripción.
Haga clic en Crear.
Haz clic en el campo Seleccionar una función.
En Todas las funciones, selecciona Cuentas de servicio > Creador de tokens de cuenta de servicio.
Haga clic en Continuar.
Haz clic en Listo para terminar de crear la cuenta de servicio.
No cierres la ventana del navegador. La usarás en el siguiente procedimiento.
Para crear una clave de cuenta de servicio, haz lo siguiente:
- En la Google Cloud consola de, haz clic en la dirección de correo electrónico de la cuenta de servicio que creaste.
- Haga clic en Claves.
- Haz clic en Agregar clave -> Crear nueva clave.
- Haz clic en Crear. Se descargará un archivo de claves JSON en tu computadora.
- Haga clic en Cerrar.
gcloud
Puedes ejecutar los siguientes comandos con Google Cloud CLI en tu máquina local o en Cloud Shell.
Configura la cuenta predeterminada para
gcloud. Si tienes más de una cuenta, asegúrate de elegir la cuenta que está en el Google Cloud proyecto que deseas usar.gcloud auth login
Muestra los IDs de tus Google Cloud proyectos de.
gcloud projects list
Configura el proyecto predeterminado. Reemplaza
PROJECT_IDpor el Google Cloud ID del proyecto de que deseas usar.gcloud config set project PROJECT_ID
Crea una cuenta de servicio. Reemplaza
SA_NAMEySA_DISPLAY_NAMEpor el nombre y el nombre comercial que deseas usar.gcloud iam service-accounts create SA_NAME \ --display-name "SA_DISPLAY_NAME"
Muestra la dirección de correo electrónico de la cuenta de servicio que acabas de crear.
gcloud iam service-accounts list
Agrega la función Creador de tokens de cuenta de servicio. Reemplaza
SA_EMAIL_ADDRESSpor la dirección de correo electrónico 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 claves de cuenta de servicio en el directorio de trabajo actual. Reemplaza
FILE_NAMEpor el nombre que deseas usar para el archivo de claves. De forma predeterminada, el comando degcloudcrea un archivo JSON.gcloud iam service-accounts keys create FILE_NAME.json \ --iam-account SA_EMAIL_ADDRESS
Consulta la
gcloud referencia
para obtener más información sobre los comandos anteriores.
Si deseas obtener información sobre cómo proteger la clave privada, consulta Recomendaciones para administrar las credenciales.
Configura tu API para admitir la autenticación
Cuando creas una configuración de API para tu puerta de enlace, especificas una cuenta de servicio que usa tu puerta de enlace para interactuar con otros servicios. Para habilitar la autenticación de cuentas de servicio para los servicios que llaman a tu puerta de enlace, modifica los objetos de seguridad en la configuración de tu API. Las modificaciones variarán según la versión de la especificación de OpenAPI que se use.
Para configurar API Gateway para validar las reclamaciones en el JWT firmado que usan los servicios de llamadas, haz lo siguiente:
OpenAPI 2.0
- Agrega la cuenta de servicio como una entidad emisora en la configuración de tu 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"
- Reemplaza
DEFINITION_NAMEpor una cadena que identifique esta definición de seguridad. Es posible que desees reemplazarlo por el nombre de la cuenta de servicio o un nombre que identifique el servicio de llamadas. - Reemplaza
SA_EMAIL_ADDRESSpor la dirección de correo electrónico de la cuenta de servicio. - Puedes establecer varias definiciones de seguridad en tu configuración de API, pero
cada definición debe tener un
x-google-issuerdiferente. Si creaste cuentas de servicio separadas para cada servicio de llamadas, puedes crear una definición de seguridad por 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"
- Reemplaza
- O bien agrega
x-google-audiencesa la secciónsecurityDefinitions. Si no agregasx-google-audiences, API Gateway requiere que la reclamación"aud"(público) en el JWT tenga el formatohttps://SERVICE_NAME, en el que SERVICE_NAME es el nombre de tu servicio de API Gateway que configuraste en el campohostde tu documento de OpenAPI. - Agrega una sección
securityal nivel superior del archivo (sin sangría ni anidado) para aplicarla en toda la API, o en el nivel de los métodos y así aplicarla a un método específico. Si usas las seccionessecurityen el nivel de la API y en el de los métodos, la configuración del nivel de los métodos anula la de la API.security: - DEFINITION_NAME: []
- Reemplaza
DEFINITION_NAMEpor el nombre que usaste en la secciónsecurityDefinitions. - Si tienes más de una definición en la sección
securityDefinitions, agrégalas en la secciónsecurity, por ejemplo:security: - service-1: [] - service-2: []
- Reemplaza
- Implementa la configuración de la API actualizada. Antes de que API Gateway reenvíe una solicitud a tu API, la puerta de enlace de API verifica lo siguiente:
- La firma del JWT mediante la clave pública, que se encuentra en el URI
especificado en el
x-google-jwks_uricampo en tu configuración de API. - Que la reclamación
"iss"(entidad emisora) en el JWT coincida con el valor especificado en elx-google-issuercampo. - Que la reclamación
"aud"(público) en el JWT contenga el nombre de tu servicio de API Gateway o coincida con uno de los valores que especificaste en elx-google-audiencescampo. - Que el token no haya vencido mediante la reclamación
"exp"(hora de vencimiento)
- La firma del JWT mediante la clave pública, que se encuentra en el URI
especificado en el
OpenAPI 3.x
- Agrega la cuenta de servicio como una entidad emisora en la configuración de tu API:
components: securitySchemes: SCHEME_NAME: type: oauth2 flows: implicit: authorizationUrl: "" scopes: {} x-google-auth: issuer: SA_EMAIL_ADDRESS jwksUri: https://www.googleapis.com/robot/v1/metadata/x509/SA_EMAIL_ADDRESS security: - SCHEME_NAME: []
- Reemplaza
SCHEME_NAMEpor una cadena que identifique este esquema de seguridad. Es posible que desees reemplazarlo por el nombre de la cuenta de servicio o un nombre que identifique el servicio de llamadas. - Reemplaza
SA_EMAIL_ADDRESSpor la dirección de correo electrónico de la cuenta de servicio. - Puedes establecer varios esquemas de seguridad en tu configuración de API, pero
cada definición debe tener un
issuerdiferente. Si creaste cuentas de servicio separadas para cada servicio de llamadas, puedes crear una definición de seguridad por cada cuenta de servicio, por ejemplo:components: securitySchemes: service-1: type: oauth2 flows: implicit: authorizationUrl: "" scopes: {} x-google-auth: issuer: "service-1@example-project-12345.iam.gserviceaccount.com" jwksUri: https://www.googleapis.com/robot/v1/metadata/x509/service-1@example-project-12345.iam.gserviceaccount.com jwtLocations: - header: Authorization valuePrefix: "Bearer " service-2: type: oauth2 flows: implicit: authorizationUrl: "" scopes: {} x-google-auth: issuer: "service-2@example-project-12345.iam.gserviceaccount.com" jwksUri: "https://www.googleapis.com/robot/v1/metadata/x509/service-2@example-project-12345.iam.gserviceaccount.com"
- Reemplaza
- O bien agrega
audiencesa la secciónsecuritySchemes. Si no agregasaudiences, API Gateway requiere que la"aud"(público) reclamación en el JWT tenga el formatohttps://SERVICE_NAME, en el que SERVICE_NAME es el nombre de tu servicio de API Gateway que configuraste en el camposervers.urlde tu documento de OpenAPI. - Agrega una sección
securityal nivel superior del archivo (sin sangría ni anidado) para aplicarla en toda la API, o en el nivel de los métodos y así aplicarla a un método específico. Si usas las seccionessecurityen el nivel de la API y en el de los métodos, la configuración del nivel de los métodos anula la de la API.security: - SCHEME_NAME: []
- Reemplaza SCHEME_NAME por el nombre que usaste en la
securitySchemessección. - Si tienes más de una definición en la sección
securitySchemes, agrégalas en la secciónsecurity, por ejemplo:security: - service-1: [] - service-2: []
- Reemplaza SCHEME_NAME por el nombre que usaste en la
- Implementa la configuración de la API actualizada. Antes de que API Gateway reenvíe una solicitud a tu API, la puerta de enlace de API verifica lo siguiente:
- La firma del JWT mediante la clave pública, que se encuentra en el URI
especificado en el
jwksUricampo en tu configuración de API. - Que la reclamación
"iss"(entidad emisora) en el JWT coincida con el valor especificado en elissuercampo. - Que la reclamación
"aud"(público) en el JWT contenga el nombre de tu servicio de API Gateway o coincida con uno de los valores que especificaste en elaudiencescampo. - Que el token no haya vencido mediante la reclamación
"exp"(hora de vencimiento)
- La firma del JWT mediante la clave pública, que se encuentra en el URI
especificado en el
Realiza una solicitud autenticada a una API de API Gateway
Para realizar una solicitud autenticada, el servicio de llamadas envía un JWT firmado por la cuenta de servicio que especificaste en la configuración de API. El servicio de llamadas debe hacer lo siguiente:
- Crear un JWT y firmarlo con la clave privada de la cuenta de servicio
- Enviar el JWT firmado en una solicitud a la API
En el siguiente código de muestra, se muestra este proceso para los lenguajes seleccionados. Si deseas realizar una solicitud autenticada en otros lenguajes, consulta jwt.io para obtener una lista de bibliotecas compatibles.
-
En el servicio de llamadas, agrega la función que sigue y pásala a los parámetros siguientes:
Java -
saKeyfile: La ruta de acceso completa al archivo de claves privadas de la cuenta de servicio -
saEmail: La dirección de correo electrónico de la cuenta de servicio -
audience: Si agregaste el campox-google-audiencesa la configuración de tu API, configuraaudiencecomo uno de los valores que especificaste parax-google-audiences. De lo contrario, configuraaudiencecomohttps://SERVICE_NAME, en el queSERVICE_NAMEes el nombre de tu servicio de API Gateway. -
expiryLength: El tiempo de vencimiento del JWT, en segundos
Python -
sa_keyfile: La ruta de acceso completa al archivo de claves privadas de la cuenta de servicio -
sa_email: La dirección de correo electrónico de la cuenta de servicio -
audience: Si agregaste el campox-google-audiencesa la configuración de tu API, configuraaudiencecomo uno de los valores que especificaste parax-google-audiences. De lo contrario, configuraaudiencecomohttps://SERVICE_NAME, en el queSERVICE_NAMEes el nombre de tu servicio de API Gateway. -
expiry_length: El tiempo de vencimiento del JWT, en segundos
Go -
saKeyfile: La ruta de acceso completa al archivo de claves privadas de la cuenta de servicio -
saEmail: La dirección de correo electrónico de la cuenta de servicio -
audience: Si agregaste el campox-google-audiencesa la configuración de tu API, configuraaudiencecomo uno de los valores que especificaste parax-google-audiences. De lo contrario, configuraaudiencecomohttps://SERVICE_NAME, en el queSERVICE_NAMEes el nombre de tu servicio de API Gateway. -
expiryLength: El tiempo de vencimiento del JWT, en segundos
La función crea un JWT, lo firma con el archivo de claves privadas y muestra el JWT firmado.
Java Python Go -
-
En el servicio de llamadas, agrega la función siguiente para enviar el JWT firmado
en el
Authorization: Bearerencabezado de la solicitud a la API:Java Python Go
Cuando envíes una solicitud con un JWT, por motivos de seguridad, te recomendamos que coloques el token de autenticación en el encabezado Authorization: Bearer. Por ejemplo:
curl --request POST \ --header "Authorization: Bearer TOKEN" \ "GATEWAY_URL/hello"
Aquí, GATEWAY_URL y TOKEN deben reemplazarse por la URL de la puerta de enlace implementada y el token de autenticación, respectivamente.
Recibe resultados autenticados en tu API
Por lo general, API Gateway reenvía todos los encabezados que recibe. Sin embargo, anula el encabezado Authorization original cuando la dirección de backend se especifica mediante x-google-backend en la configuración de la API.
API Gateway enviará el resultado de la autenticación en 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.