Saltar al contenido
ecdsa.com
jose (JavaScript)Bibliotecas de JWT

Mensaje de error

unexpected "iss" claim value

jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED

Qué significa

El token superó la verificación criptográfica, pero su claim (declaración) `iss` no es igual a la opción `issuer` que pasas a `jwtVerify`. jose compara las cadenas de forma exacta (también acepta un array de emisores permitidos), así que cualquier diferencia —una barra final, otra ruta de inquilino, otro entorno— hace fallar la comprobación. La fijación del emisor es lo que impide que se acepte un token de otro proveedor de identidad o de otro inquilino del mismo proveedor.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    Tomar la cadena del emisor del documento de descubrimiento

    El valor `issuer` de `/.well-known/openid-configuration` es, por especificación, exactamente lo que el proveedor escribe en `iss`. Cópialo byte a byte en tu configuración.

    bash
    # The issuer string is defined by the provider's discovery document.
    curl -s https://login.example.com/.well-known/openid-configuration | jq -r .issuer
  2. 2.

    Fijar ese valor exacto en jwtVerify

    Mantén la opción `issuer` —sin ella, jose no comprueba `iss` en absoluto— y guárdala en una única constante que compartan la URL del JWKS y el verificador.

    js
    import { createRemoteJWKSet, jwtVerify } from "jose";
    
    const ISSUER = "https://login.example.com/"; // exactly as in "issuer" from discovery
    const jwks = createRemoteJWKSet(new URL("https://login.example.com/.well-known/jwks.json"));
    
    const { payload } = await jwtVerify(token, jwks, { algorithms: ["ES256"], issuer: ISSUER });
  3. 3.

    Aceptar varios emisores, cada uno con su conjunto de claves

    Si tu servicio confía realmente en más de un emisor, selecciona el conjunto de claves según el `iss` (aún sin verificar) del token a partir de una lista de permitidos explícita y, después, verifica con ese emisor fijado. Nunca dejes que las claves de un emisor verifiquen los tokens de otro.

    js
    import { createRemoteJWKSet, decodeJwt, jwtVerify } from "jose";
    
    // Each trusted issuer gets its own key set; an unknown iss is rejected before any key is used.
    const trusted = new Map([
      ["https://login.example.com/", createRemoteJWKSet(new URL("https://login.example.com/.well-known/jwks.json"))],
      ["https://partner.example.org", createRemoteJWKSet(new URL("https://partner.example.org/jwks"))],
    ]);
    
    const { iss } = decodeJwt(token);
    const keys = trusted.get(iss);
    if (!keys) throw new Error("untrusted issuer");
    await jwtVerify(token, keys, { algorithms: ["ES256", "RS256"], issuer: iss });

Errores relacionados

Explorar toda la base de datos de errores de firma