本文へスキップ
ecdsa.com
jose (JavaScript)JWT ライブラリ

エラーメッセージ

unexpected "iss" claim value

jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED

このエラーの意味

トークンは暗号的な検証には成功しましたが、`iss` クレームが `jwtVerify` に渡した `issuer` オプションと一致しません。jose は文字列を完全一致で比較するため(許可する発行者の配列も指定できます)、末尾のスラッシュ、テナントのパスの違い、別の環境など、どんな違いがあっても確認に失敗します。発行者を固定することで、別の ID プロバイダーや、同じプロバイダーの別テナントのトークンが受け入れられるのを防げます。

発生する理由

修正方法

  1. 1.

    ディスカバリドキュメントから発行者の文字列を取得する

    `/.well-known/openid-configuration` の `issuer` の値は、仕様上、プロバイダーが `iss` に書き込む値とまったく同じです。これを 1 バイトも変えずに設定にコピーしてください。

    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.

    その値をそのまま jwtVerify に固定する

    `issuer` オプションは残してください(これがないと、jose は `iss` をまったく確認しません)。また、その値は JWKS の URL と検証者で共有する 1 つの定数にまとめてください。

    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.

    発行者ごとに鍵セットを分けて複数の発行者を受け入れる

    サービスが本当に複数の発行者を信頼する場合は、トークンの(未検証の)`iss` をもとに明示的な許可リストから鍵セットを選び、その発行者を固定したうえで検証してください。ある発行者の鍵で別の発行者のトークンを検証させてはいけません。

    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 });

関連するエラー

署名エラーデータベースをすべて見る