Delegación de servicio a servicio
En algunas arquitecturas de API, un servicio backend recibe una solicitud de un usuario autenticado y necesita llamar a otro servicio backend mientras preserva la identidad del usuario.
Por ejemplo:
Usuario -> API A -> API B
API B necesita saber dos cosas:
- El llamador es un servicio confiable, como API A.
- La operación se está realizando para el usuario original.
Utiliza la concesión de intercambio de tokens de Logto para intercambiar el token de acceso del usuario por un nuevo token de acceso cuyo público sea el recurso de API downstream. Esto sigue el patrón de intercambio de tokens de OAuth 2.0 y evita reenviar el token original del usuario a los servicios downstream.
Cuándo usar este flujo
Utiliza la delegación de servicio a servicio cuando:
- API A es un servicio backend que puede autenticarse de forma segura en el endpoint de token de Logto.
- API A recibe un token de acceso de usuario emitido por Logto.
- API A necesita llamar a API B en nombre del mismo usuario.
- API B debe validar un token de acceso con su propio recurso de API como audiencia.
No utilices este flujo para acceso puramente máquina a máquina sin un usuario. En ese caso, utiliza el flujo de credenciales de cliente. Para escenarios de soporte, administración o agente donde un usuario actúa temporalmente como otro usuario, utiliza la suplantación de usuario.
Cómo funciona
El token de acceso intercambiado representa al usuario original (sub) y está vinculado al recurso de API downstream (aud). La API downstream también puede inspeccionar el reclamo client_id para identificar la aplicación que inició el intercambio.
Requisitos previos
- Crea recursos de API para los servicios involucrados. Consulta Proteger recursos de API globales.
- Configura los permisos de API B y asígnalos a los usuarios a través de roles o roles de organización.
- Utiliza una aplicación del lado del servidor para API A, como una aplicación máquina a máquina o una aplicación web tradicional, para que pueda autenticarse de forma segura con un secreto de aplicación.
- Habilita el intercambio de tokens para la aplicación de API A.
Antes de utilizar la concesión de intercambio de tokens, necesitas habilitarla para tu aplicación:
- Ve a Consola > Aplicaciones y selecciona tu aplicación.
- En la configuración de la aplicación, busca la sección "Intercambio de tokens".
- Activa el interruptor "Permitir intercambio de tokens".
El intercambio de tokens está deshabilitado por defecto por razones de seguridad. Si no lo habilitas, recibirás un error que indica "el intercambio de tokens no está permitido para esta aplicación".
Solicitar un token de acceso para la API downstream
Cuando API A necesita llamar a API B, realiza una solicitud de intercambio de tokens al endpoint de token de Logto.
Para aplicaciones web tradicionales o aplicaciones máquina a máquina con un secreto de aplicación, incluye las credenciales en el encabezado Authorization:
POST /oidc/token HTTP/1.1
Host: tenant.logto.app
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(api-a-app-id:api-a-app-secret)>
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=<user_access_token_received_by_api_a>
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&resource=https://api-b.example.com
&scope=read:orders
Parámetros:
grant_type: Usaurn:ietf:params:oauth:grant-type:token-exchange.subject_token: El token de acceso de usuario emitido por Logto recibido por API A.subject_token_type: Usaurn:ietf:params:oauth:token-type:access_token.resource: El indicador de recurso de API de API B.scope: Los permisos downstream que API A solicita para esta llamada delegada. Logto emite solo los alcances solicitados que están disponibles para el usuario original para este recurso según la configuración de RBAC.
Logto devuelve un token de acceso para API B:
{
"access_token": "eyJhbGci...<truncado>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read:orders"
}
Al decodificarlo, el token de acceso incluye reclamos similares a:
{
"sub": "user_id",
"client_id": "api_a_app_id",
"iss": "https://tenant.logto.app/oidc",
"aud": "https://api-b.example.com",
"scope": "read:orders",
"exp": 1760000000
}
Luego, API A llama a API B con el token intercambiado:
GET /orders HTTP/1.1
Host: api-b.example.com
Authorization: Bearer <exchanged_access_token>
Validar el token en API B
API B debe validar el token intercambiado igual que cualquier token de acceso de recurso de API emitido por Logto:
- Verifica la firma usando los JWKs de Logto.
- Verifica el emisor (
iss). - Verifica que la audiencia (
aud) coincida con el indicador de recurso de API B. - Verifica la expiración (
exp). - Verifica los alcances requeridos.
- Usa
subcomo el ID de usuario original. - Opcionalmente verifica
client_idsi solo se permite que servicios upstream específicos realicen llamadas delegadas.
Consulta Validar tokens de acceso en API para orientación sobre la implementación.