VerifyJWT ポリシー

このページは ApigeeApigee ハイブリッドに適用されます。

Apigee Edge のドキュメントはこちらをご覧ください。

ポリシー アイコン

概要

署名付き JWT を検証します。また、クライアントや他のシステムから受信した暗号化された JWT を復号して検証します。このポリシーはクレームをコンテキスト変数に抽出し、後続のポリシーまたは条件でそれらの値を調べて、認可やルーティングを決定できるようにします。詳細については、JWS ポリシーと JWT ポリシーの概要をご覧ください。

このポリシーは、標準ポリシーであり、任意の環境タイプにデプロイできます。すべてのユーザーがポリシーや環境のタイプを知る必要はありません。ポリシータイプと各環境タイプで使用可能かどうかは、ポリシータイプをご覧ください。

署名付き JWT の場合、このポリシーが実行されると、Apigee は指定された検証鍵を使用して JWT の署名を検証します。暗号化された JWT の場合、Apigee は復号鍵を使用して JWT を復号します。いずれの場合も、Apigee は、有効期限と not-before 値に基づいて JWT が有効であることを検証します。このポリシーは必要に応じて、JWT の特定のクレームの値(サブジェクト、発行者、オーディエンス、追加のクレームの値など)を確認することもできます。

検証の結果、JWT が有効である場合、JWT に含まれるすべてのクレームが抽出されて後続のポリシーや条件で使用できるようにコンテキスト変数に格納され、リクエストの続行が許可されます。JWT の署名を検証できない場合、またはタイムスタンプが原因で JWT が無効な場合は、すべての処理が停止され、レスポンスでエラーが返されます。

JWT の各部について、またその暗号化と署名の方法については、RFC7519 をご覧ください。

方法

ポリシーが署名付き JWT と暗号化された JWT のどちらを検証するかは、JWT を検証するアルゴリズムの指定に使用する要素によって異なります。

動画

JWT の署名を検証する方法についての動画をご覧ください。

署名付き JWT を検証する

このセクションでは、署名付き JWT を検証する方法について説明します。署名付き JWT の場合は、<Algorithm> 要素を使用して、鍵の署名アルゴリズムを指定します。

署名付き JWT のサンプル

次のサンプルは、署名付き JWT の検証方法を示しています。

HS256 アルゴリズム

このポリシー サンプルでは、HS256 暗号化アルゴリズム(SHA-256 チェックサムを使用した HMAC)で署名された JWT を検証します。JWT は、jwt という名前のフォーム パラメータを介してプロキシ リクエスト内で渡されます。鍵は private.secretkey という名前の変数に含まれています。ポリシーにリクエストを送信する方法など、詳しい例については、上記の動画をご覧ください。

ポリシー構成には、Apigee が JWT のデコードと評価に必要とする情報が含まれます。たとえば、JWT の参照先(Source 要素で指定されたフロー変数内)、必要な署名アルゴリズム、秘密鍵の場所(Apigee フロー変数に格納され、Apigee KVM から取得可能など)などです。

<VerifyJWT name="JWT-Verify-HS256">
    <DisplayName>JWT Verify HS256</DisplayName>
    <Algorithm>HS256</Algorithm>
    <Source>request.formparam.jwt</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <SecretKey encoding="base64">
        <Value ref="private.secretkey"/>
    </SecretKey>
    <Subject>monty-pythons-flying-circus</Subject>
    <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
    <Audience>fans</Audience>
    <AdditionalClaims>
        <Claim name="show">And now for something completely different.</Claim>
    </AdditionalClaims>
</VerifyJWT>

ポリシーが出力をコンテキスト変数に書き込むため、API プロキシの後続のポリシーまたは条件でそれらの値を調べることができます。このポリシーの変数のリストについては、フロー変数をご覧ください。

RS256 アルゴリズム

このポリシー サンプルでは、RS256 アルゴリズムで署名された JWT を検証します。検証するには公開鍵を用意する必要があります。JWT は、jwt という名前のフォーム パラメータを介してプロキシ リクエスト内で渡されます。公開鍵は public.publickey という名前の変数に含まれています。ポリシーにリクエストを送信する方法など、詳しい例については、上記の動画をご覧ください。

このサンプル ポリシーの各要素に関する要件とオプションの詳細については、要素リファレンスをご覧ください。

<VerifyJWT name="JWT-Verify-RS256">
    <Algorithm>RS256</Algorithm>
    <Source>request.formparam.jwt</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <PublicKey>
        <Value ref="public.publickey"/>
    </PublicKey>
    <Subject>apigee-seattle-hatrack-montage</Subject>
    <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
    <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience>
    <AdditionalClaims>
        <Claim name="show">And now for something completely different.</Claim>
    </AdditionalClaims>
</VerifyJWT>

上記のポリシー構成に対し、JWT が以下のヘッダーを含み、

{
  "typ" : "JWT",
  "alg" : "RS256"
}

かつ、以下のペイロードを含む場合、

{
  "sub" : "apigee-seattle-hatrack-montage",
  "iss" : "urn://apigee-edge-JWT-policy-test",
  "aud" : "urn://c60511c0-12a2-473c-80fd-42528eb65a6a",
  "show": "And now for something completely different."
}

指定された公開鍵で署名を検証できれば、この JWT は有効とみなされます。

上記と同じヘッダーで以下のペイロードを含む JWT の場合、

{
  "sub" : "monty-pythons-flying-circus",
  "iss" : "urn://apigee-edge-JWT-policy-test",
  "aud" : "urn://c60511c0-12a2-473c-80fd-42528eb65a6a",
  "show": "And now for something completely different."
}

JWT に含まれるサブクレームが、ポリシー構成で指定されたサブジェクト要素の必須の値と一致しないため、署名の検証が可能であっても無効と判断されます。

ポリシーが出力をコンテキスト変数に書き込むため、API プロキシの後続のポリシーまたは条件でそれらの値を調べることができます。このポリシーの変数のリストについては、フロー変数をご覧ください。

上記のサンプルでは <Algorithm> 要素を使用しているため、署名付き JWT を検証しています。<PrivateKey> 要素には、JWT の署名に使用される鍵を指定します。他にも重要な要素があります。どちらを使用するかは、次のセクションで説明するように、<Algorithm> の値で指定されたアルゴリズムによって異なります。

署名付き JWT を検証するための鍵要素の設定

次の要素では、署名付き JWT の検証に使用される鍵を指定します。

次の表に示すように、使用する要素は選択したアルゴリズムによって異なります。

アルゴリズム 鍵要素
HS*

<SecretKey encoding="base16|hex|base64|base64url">
  <Value ref="private.secretkey"/>
</SecretKey>
RS*、ES*、PS*

<PublicKey>
  <Value ref="rsa_public_key_or_value"/>
</PublicKey>

または


<PublicKey>
  <Certificate ref="signed_cert_val_ref"/>
</PublicKey>

または


<PublicKey>
  <JWKS ref="jwks_val_or_ref"/>
</PublicKey>
* 鍵の要件については、署名の暗号化アルゴリズムについてをご覧ください。

暗号化された JWT を確認する

このセクションでは、暗号化された JWT を検証する方法について説明します。暗号化された JWT の場合は、<Algorithms> 要素を使用して、鍵とコンテンツの署名アルゴリズムを指定します。

暗号化された JWT のサンプル

次のサンプルは、暗号化された JWT を検証する方法を示しています(<Type>Encrypted に設定)。

  • 鍵は RSA-OAEP-256 アルゴリズムで暗号化されます。
  • コンテンツは A128GCM アルゴリズムで暗号化されます。
<VerifyJWT name="vjwt-1">
  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>
  <Type>Encrypted</Type> 
  <PrivateKey>
    <Value ref="private.rsa_privatekey"/>
  </PrivateKey>
  <Subject>subject@example.com</Subject>
  <Issuer>urn://apigee</Issuer>
  <AdditionalHeaders>
    <Claim name="moniker">Harvey</Claim>
  </AdditionalHeaders>
  <TimeAllowance>30s</TimeAllowance>
  <Source>input_var</Source>
</VerifyJWT>

上のサンプルでは <Algorithms> 要素を使用しているため、暗号化された JWT を検証しています。<PrivateKey> 要素には、JWT の復号に使用される鍵を指定します。他にも重要な要素があります。どちらを使用するかは、次のセクションで説明するように、<Algorithms> の値で指定されたアルゴリズムによって異なります。

暗号化された JWT を検証するための鍵要素の設定

次の要素では、暗号化された JWT の検証に使用する鍵を指定します。

次の表に示すように、使用する要素は選択した鍵暗号化アルゴリズムによって異なります。

アルゴリズム 鍵要素
RSA-OAEP-256

<PrivateKey>
  <Value ref="private.rsa_privatekey"/>
</PrivateKey>

注: 指定する変数は、PEM でエンコードされた形式の RSA 秘密鍵に解決する必要があります。

  • ECDH-ES
  • ECDH-ES+A128KW
  • ECDH-ES+A192KW
  • ECDH-ES+A256KW

<PrivateKey>
  <Value ref="private.ec_privatekey"/>
</PrivateKey>

注: 指定する変数は、PEM でエンコードされた楕円曲線の秘密鍵に解決される必要があります。

  • A128KW
  • A192KW
  • A256KW
  • A128GCMKW
  • A192GCMKW
  • A256GCMKW

<SecretKey encoding="base16|hex|base64|base64url">
  <Value ref="private.flow-variable-name-here"/>
</SecretKey>
  • PBES2-HS256+A128KW
  • PBES2-HS384+A192KW
  • PBES2-HS512+A256KW

<PasswordKey>
  <Value ref="private.password-key"/>
  <SaltLength>
  <PBKDF2Iterations>
</PasswordKey>
dir

<DirectKey>
  <Value encoding="base16|hex|base64|base64url" ref="private.directkey"/>
</DirectKey>

鍵の要件について詳しくは、署名暗号アルゴリズムについてをご覧ください。

要素リファレンス

このポリシー リファレンスでは、VerifyJWT ポリシーの要素と属性について説明しています。

注: 構成は、使用する暗号化アルゴリズムによって多少異なります。特定のユースケースの構成例については、サンプルをご覧ください。

最上位の要素に適用される属性


<VerifyJWT name="JWT" continueOnError="false" enabled="true" async="false">

次の属性は、すべてのポリシーの親要素に共通です。

属性 説明 デフォルト 要否
name ポリシーの内部名。名前に使用できる文字は A-Z0-9._\-$ % のみです。ただし、Apigee UI には追加の制限があり、英数字以外の文字は自動的に削除されます。

必要に応じて、<displayname></displayname> 要素を使用して、管理 UI プロキシ エディタでポリシーに別の自然言語名でラベルを付けます。

なし 必須
continueOnError ポリシーが失敗したときにエラーを返す場合は、false に設定します。これは、ほとんどのポリシーで想定される動作です。

ポリシーが失敗した後もフローの実行を続行する場合は、true に設定します。

false 省略可
有効 ポリシーを適用するには、true に設定します。

ポリシーを無効にするには、false に設定します。ポリシーがフローに接続されている場合でも適用されません。

true 省略可
非同期 この属性は非推奨となりました。 false 非推奨

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

name 属性に加えて、管理 UI プロキシ エディタでポリシーを別の自然言語名でラベル付けするために使用します。

デフォルト この要素を省略した場合、ポリシーの name 属性の値が使用されます。
要否 省略可
文字列

<Algorithm>

<Algorithm>HS256</Algorithm>

トークンの検証に使用される暗号アルゴリズムを指定します。<Algorithm> 要素を使用して、署名付き JWT を検証します。

RS*、PS*、ES* の各アルゴリズムでは公開鍵 / 秘密鍵ペアを使用し、HS* アルゴリズムでは共有シークレットを使用します。署名の暗号化アルゴリズムについてもご覧ください。

複数の値をカンマで区切りながら指定できます。たとえば、「HS256, HS512」や「RS256, PS256」とします。ただし、必要な鍵の種類が異なるため、HS* アルゴリズムとその他のアルゴリズム、または ES* アルゴリズムとその他のアルゴリズムを組み合わせることはできません。RS* アルゴリズムと PS* アルゴリズムは組み合わせることができます。

デフォルト 該当なし
要否 必須
カンマ区切り値の文字列
有効な値 HS256、HS384、HS512、RS256、RS384、RS512、ES256、ES384、ES512、PS256、PS384、PS512

<Algorithms>

<Algorithms>
    <Key>key-algorithm</Key>
    <Content>content-algorithm</Content>
</Algorithm>

<Algorithms> 要素を使用して、暗号化された JWT を検証します。この要素により、暗号化された JWT を作成する際に使用した鍵暗号化の暗号アルゴリズムを指定します。また、必要に応じてコンテンツ暗号化のアルゴリズムも指定します。

デフォルト 該当なし
要否 暗号化された JWT を検証する場合は必須
複雑

<Algorithms> の子要素

次の表は、<Algorithms> の子要素の概要をまとめたものです。

子要素 必須かどうか 説明
<Key> 必須 鍵の暗号化アルゴリズムを指定します。
<Content> 省略可 コンテンツの暗号化アルゴリズムを指定します。

次の場合は検証に失敗します。

  • 暗号化された JWT のヘッダーにある alg プロパティでアサートされるアルゴリズムは、この <Key> 要素で指定された鍵暗号化アルゴリズムとは異なります。
  • このポリシーでは <Content> 要素が指定され、暗号化された JWT のヘッダーにある enc プロパティでアサートされるアルゴリズムは、<Content> 要素で指定されたアルゴリズムとは異なります。

たとえば、暗号化された JWT を検証し、鍵アルゴリズムが RSA-OAEP-256 であり、コンテンツ アルゴリズムが A128GCM であることを確認するには、次のようにします。

  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>

逆に、暗号化された JWT を検証し、鍵アルゴリズムが RSA-OAEP-256 であり、コンテンツ アルゴリズムに制約を適用していないことを確認するには、次のようにします。

  <Algorithms>
    <Key>RSA-OAEP-256</Key>
  </Algorithms>

鍵暗号化アルゴリズム

次の表に、鍵の暗号化に使用できるアルゴリズムと、その鍵暗号化アルゴリズムを使用して JWT を検証するために指定する必要がある鍵のタイプを示します。

<Key>(鍵暗号化アルゴリズム)の値 検証に必要な鍵要素
dir <DirectKey>
RSA-OAEP-256 <PrivateKey>
  • A128KW
  • A192KW
  • A256KW
  • A128GCMKW
  • A192GCMKW
  • A256GCMKW
<SecretKey>
  • PBES2-HS256+A128KW
  • PBES2-HS384+A192KW
  • PBES2-HS512+A256KW
<PasswordKey>
  • ECDH-ES
  • ECDH-ES+A128KW
  • ECDH-ES+A192KW
  • ECDH-ES+A256KW
<PrivateKey>

鍵の暗号化アルゴリズムが RSA-OAEP-256 になっている例については、暗号化された JWT を検証するをご覧ください。ここでは <PrivateKey> 要素を使用します。

コンテンツ暗号化アルゴリズム

VerifyJWT ポリシーでは、コンテンツ暗号化のアルゴリズムを指定する必要はありません。コンテンツ暗号化に使用するアルゴリズムを指定するには、<Algorithms> 要素の <Content> 子を指定します。

鍵暗号化アルゴリズムに関係なく、コンテンツ暗号化では次のアルゴリズム(対称および AES ベースの両方)がサポートされています。

  • A128CBC-HS256
  • A192CBC-HS384
  • A256CBC-HS512
  • A128GCM
  • A192GCM
  • A256GCM

<Audience>


<Audience>audience-here</Audience>

or:

<Audience ref='variable-name-here'/>

このポリシーでは、JWT のオーディエンス クレームが、構成で指定された値と一致することを検証します。一致しない場合、ポリシーはエラーを返します。このクレームは、この JWT の受け取りを想定された対象を指定します。これは、RFC7519 に記載されている登録済みクレームの一つです。

デフォルト 該当なし
要否 省略可
文字列
有効な値 オーディエンスを識別するフロー変数または文字列

<AdditionalClaims/Claim>

<AdditionalClaims>
    <Claim name='claim1'>explicit-value-of-claim-here</Claim>
    <Claim name='claim2' ref='variable-name-here'/>
    <Claim name='claim3' ref='variable-name-here' type='boolean'/>
</AdditionalClaims>

or:

<AdditionalClaims ref='claim_payload'/>

指定された追加クレームが JWT ペイロードに含まれていることと、アサートされたクレーム値が一致することを検証します。

追加クレームには、標準 JWT クレーム名や登録済み JWT クレーム名以外の名前を使用します。追加クレームの値は、文字列、数値、ブール値、マッピング、または配列です。マップとは、名前と値のペアのセットのことです。こうしたタイプのクレームの値は、ポリシー構成で明示的に指定することも、フロー変数への参照によって間接的に指定することもできます。

デフォルト 該当なし
要否 省略可
文字列、数値、ブール値、マッピング
配列 (省略可)値が型の配列かどうかを示すには true に設定しますデフォルト: false
有効な値 追加のクレームに使用する任意の値。

<Claim> 要素には次の属性があります。

  • name -(必須)クレームの名前。
  • ref -(省略可)フロー変数の名前。設定された場合、ポリシーはこの変数の値をクレームとして使用します。ref 属性と明示的なクレーム値の両方が指定された場合、明示的な値がデフォルトとなり、参照されたフロー変数が解決されない場合に使用されます。
  • type -(省略可)文字列(デフォルト)、数値、ブール値、マッピングのいずれか
  • array -(省略可)値が型の配列かどうかを示すには true に設定します。デフォルト: false

<Claim> 要素を含める場合、クレーム名はポリシーの構成時に静的に設定します。あるいは、JSON オブジェクトを渡してクレーム名を指定することもできます。JSON オブジェクトは変数として渡されるため、クレーム名はランタイムに判定されます。

次に例を示します。

<AdditionalClaims ref='json_claims'/>

ここで、変数 json_claims には次の形式の JSON オブジェクトが含まれます。

{
  "sub" : "person@example.com",
  "iss" : "urn://secure-issuer@example.com",
  "non-registered-claim" : {
    "This-is-a-thing" : 817,
    "https://example.com/foobar" : { "p": 42, "q": false }
  }
}

<AdditionalHeaders/Claim>

<AdditionalHeaders>
    <Claim name='claim1'>explicit-value-of-claim-here</Claim>
    <Claim name='claim2' ref='variable-name-here'/>
    <Claim name='claim3' ref='variable-name-here' type='boolean'/>
    <Claim name='claim4' ref='variable-name' type='string' array='true'/>
</AdditionalHeaders>

指定された追加クレームの名前と値のペアが JWT ヘッダーに含まれていることと、アサートされたクレーム値が一致していることを検証します。

追加クレームには、標準 JWT クレーム名や登録済み JWT クレーム名以外の名前を使用します。追加クレームの値は、文字列、数値、ブール値、マッピング、または配列です。マップとは、名前と値のペアのセットのことです。こうしたタイプのクレームの値は、ポリシー構成で明示的に指定することも、フロー変数への参照によって間接的に指定することもできます。

デフォルト 該当なし
要否 省略可

文字列(デフォルト)、数値、ブール値、マッピング

明示的に指定しない場合、デフォルトで文字列型になります。

配列 (省略可)値が型の配列かどうかを示すには true に設定しますデフォルト: false
有効な値 追加のクレームに使用する任意の値。

<Claim> 要素には次の属性があります。

  • name -(必須)クレームの名前。
  • ref -(省略可)フロー変数の名前。設定された場合、ポリシーはこの変数の値をクレームとして使用します。ref 属性と明示的なクレーム値の両方が指定された場合、明示的な値がデフォルトとなり、参照されたフロー変数が解決されない場合に使用されます。
  • type -(省略可)文字列(デフォルト)、数値、ブール値、マッピングのいずれか
  • array -(省略可)値が型の配列かどうかを示すには true に設定します。デフォルト: false

<CustomClaims>

注: 現在、UI を使用して新しい GenerateJWT ポリシーを追加すると CustomClaims 要素が挿入されます。この要素は機能していないため無視されます。代わりに使用する要素は <AdditionalClaims> です。正しい要素が挿入されるように UI が更新される予定です。

<Id>

<Id>explicit-jti-value-here</Id>
 -or-
<Id ref='variable-name-here'/>
 -or-
<Id/>

JWT に特定の jti クレームがあることを確認します。text 値と ref 属性が両方とも空白の場合、ポリシーはランダムな UUID を含む jti を生成します。JWT ID(jti)クレームは、JWT の一意の識別子です。jti の詳細については、RFC7519 をご覧ください。

デフォルト 該当なし
要否 省略可
文字列または参照。
有効な値 文字列または ID を含むフロー変数の名前。

<IgnoreCriticalHeaders>

<IgnoreCriticalHeaders>true|false</IgnoreCriticalHeaders>

false に設定すると、JWT の crit ヘッダーにリストされたヘッダーの中に、<KnownHeaders> 要素のリストにないものがあった場合に、ポリシーがエラーを返します。true に設定すると、VerifyJWT ポリシーで crit ヘッダーが無視されます。

この要素を true に設定する状況の一つとして、テスト環境で、ヘッダー不足によるエラーの対応に準備がまだできていない場合があります。

デフォルト false
要否 省略可
ブール値
有効な値 true または false

<IgnoreIssuedAt>

<IgnoreIssuedAt>true|false</IgnoreIssuedAt>

false に設定すると(デフォルト)、未来の時刻を指定する iat(Issued at)クレームが JWT に含まれていた場合に、ポリシーがエラーを返します。true に設定すると、ポリシーが検証時に iat を無視します。

デフォルト false
要否 省略可
ブール値
有効な値 true または false

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

false に設定すると、ポリシーで指定された参照値が解決できない場合にエラーを返します。true に設定すると、解決できない変数を空の文字列(null)として扱います。

デフォルト false
要否 省略可
ブール値
有効な値 true または false

<Issuer>

<Issuer>issuer-string-here</Issuer>
-or-
<Issuer ref='variable-name-here'/>

このポリシーは、JWT の発行者がポリシー構成の要素に指定された文字列と一致することを検証します。JWT の発行元を識別するクレームで、これは IETF RFC 7519 に記載されている一連の登録済みクレームの一つです。

デフォルト 該当なし
要否 省略可
文字列または参照
有効な値 すべて

<KnownHeaders>

<KnownHeaders>a,b,c</KnownHeaders>

or:

<KnownHeaders ref='variable_containing_headers'/>

GenerateJWT ポリシーでは <CriticalHeaders> 要素を使用して、crit ヘッダーを JWT に挿入します。次に例を示します。

{
  "typ": "...",
  "alg" : "...",
  "crit" : [ "a", "b", "c" ],
}

VerifyJWT ポリシーは JWT の crit ヘッダーを調べ、存在する場合は、そこにリストされた各ヘッダーが <KnownHeaders> 要素にもリストされているかどうか確認します。<KnownHeaders> 要素には、crit にリストされた項目のスーパーセットを含めることができます。必要なことは、crit にリストされたすべてのヘッダーが <KnownHeaders> 要素にリストされていることです。ポリシーが crit で検出したヘッダーの中に <KnownHeaders> に記述されていないものがあると、VerifyJWT ポリシーは失敗します。

<IgnoreCriticalHeaders> 要素を true に設定することで、VerifyJWT ポリシーが crit ヘッダーを無視するよう構成することもできます。

デフォルト 該当なし
要否 省略可
文字列のカンマ区切り配列
有効な値 配列または配列を含む変数の名前。

<MaxLifespan>

  <VerifyJWT name='xxx'>
  ...
  <!-- hard-coded lifespan of 5 minutes -->
  <MaxLifespan>5m</MaxLifespan>

  or:

  <!-- refer to a variable -->
  <MaxLifespan ref='variable-here'/>

  or:

  <!-- attribute telling the policy to use iat rather than nbf -->
  <MaxLifespan useIssueTime='true'>1h</MaxLifespan>

  or:

  <!-- useIssueTime and ref, and hard-coded fallback value. -->
  <MaxLifespan useIssueTime='true' ref='variable-here'>1h</MaxLifespan>
  ...
  

トークンの有効期限が、指定したしきい値を超えていないことを確認するように VerifyJWT ポリシーを構成します。しきい値を指定するには、数字の後に秒、分、時間、日、週を表す文字を指定します。有効な文字は次のとおりです。

  • s - 秒
  • m - 分
  • h - 時間
  • d - 日
  • w - 週

たとえば、120s、10m、1h、7d、3w のいずれかの値を指定できます。

このポリシーは、有効期限の値 (exp) から not-before 値 (nbf) を減算して、トークンの実際の有効期間を計算します。exp または nbf のいずれかが欠落している場合、ポリシーはエラーをスローします。トークンの有効期限が指定の期間を超えると、ポリシーはエラーをスローします。

トークンの有効期限を計算するときは、オプションの属性 useIssueTimetrue に設定して、nbf 値の代わりに iat 値を使用できます。

MaxLifespan 要素の使用は任意です。この要素を使用する場合は、1 回しか使用できません。

<PrivateKey>

この要素により、非対称アルゴリズムで暗号化された JWT の検証に使用できる秘密鍵を指定します。可能性のある子要素については、後述します。

<Password>

<PrivateKey>
  <Password ref="private.privatekey-password"/>
</PrivateKey>

<PrivateKey> 要素の子要素。暗号化された JWT を検証する際に、必要に応じて、ポリシーで秘密鍵の復号に使用するパスワードを指定します。ref 属性を使用して、パスワードをフロー変数に渡します。

デフォルト 該当なし
要否 省略可
文字列
有効な値 フロー変数の参照。

注: フロー変数を指定する必要があります。パスワードが平文で指定されているポリシー構成は無効として拒否されます。フロー変数には接頭辞 private が必要です。たとえば、private.mypassword のようにします。

<Value>

<PrivateKey>
  <Value ref="private.variable-name-here"/>
</PrivateKey>

<PrivateKey> 要素の子要素。暗号化された JWT を検証するためにポリシーが使用する、PEM エンコードされた秘密鍵を指定します。ref 属性を使用して、鍵をフロー変数に渡します。

デフォルト 該当なし
要否 非対称鍵の暗号化アルゴリズムで暗号化された JWT を検証するために必要です。
文字列
有効な値 PEM エンコードされた RSA 秘密鍵の値を表す文字列を含むフロー変数。

注: フロー変数には接頭辞 private が必要です。たとえば、private.mykey のようにします。

<PublicKey>

非対称アルゴリズムで署名された JWT の検証に使用する公開鍵のソースを指定します。RS256/RS384/RS512、PS256/PS384/PS512、ES256/ES384/ES512 のアルゴリズムがサポートされています。子要素については、後述します。

<Certificate>

<PublicKey>
  <Certificate ref="signed_public.cert"/>
</PublicKey>

-or-

<PublicKey>
  <Certificate>
-----BEGIN CERTIFICATE-----
cert data
-----END CERTIFICATE-----
  </Certificate>
</PublicKey>

<PublicKey> 要素の子要素。公開鍵のソースとして使用される署名付き証明書を指定します。ref 属性を使用して、フロー変数の署名付き証明書を渡すか、PEM でエンコードされた証明書を直接指定します。

デフォルト 該当なし
要否 省略可。非対称アルゴリズムで署名された JWT を検証するには、<Certificate><JWKS> または <Value> 要素を使用して公開鍵を指定する必要があります。
文字列
有効な値 フロー変数または文字列。

<JWKS>

  <PublicKey>
    <JWKS …  > … </JWKS>
  </PublicKey>

<PublicKey> 要素の子要素。公開鍵のソースとして JWKS を指定します。これは、IETF RFC 7517 - JSON Web Key(JWK)で説明されている形式に従った鍵のリストになります。

インバウンド JWT が JWKS に存在する鍵 ID を保持している場合、ポリシーは正しい公開鍵を使用して JWT 署名を検証します。この機能の詳細については、JSON Web Key Set(JWKS)を使用した JWT の検証をご覧ください。

公開 URL から値を取得した場合、Apigee は JWKS を 300 秒間キャッシュに保存します。キャッシュが期限切れになると、Apigee は再度 JWKS を取得します。

デフォルト 該当なし
要否 省略可。非対称アルゴリズムで署名された JWT を検証するには、<Certificate><JWKS> または <Value> 要素を使用して公開鍵を指定する必要があります。
文字列
有効な値

JWKS は次の 4 つの方法のいずれかで指定できます。

  • 文字通り、テキスト値として:

    
      <PublicKey>
        <JWKS>{
          "keys": [
            {"kty":"RSA","e":"AQAB","kid":"b3918c88","n":"jxdm..."},
            {"kty":"RSA","e":"AQAB","kid":"24f094d4","n":"kWRdbgMQ..."}
          ]
        }
        </JWKS>
      </PublicKey>
  • フロー変数を指定して ref 属性で間接的に:

    
      <PublicKey>
        <JWKS ref="variable-containing-jwks-content"/>
      </PublicKey>

    参照される変数には、JWKS を表す文字列が含まれている必要があります。

  • uri 属性を使用して静的 URI で間接的に:

    
      <PublicKey>
        <JWKS uri="uri-that-returns-a-jwks"/>
      </PublicKey>
  • uriRef 属性を使用して動的に決定される URI で間接的に:

    
      <PublicKey>
        <JWKS uriRef="variable-containing-a-uri-that-returns-a-jwks"/>
      </PublicKey>

<Value>

<PublicKey>
  <Value ref="public.publickeyorcert"/>
</PublicKey>

-or-

<PublicKey>
  <Value>
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw2kPrRzcufvUNHvTH/WW
...YOUR PUBLIC KEY MATERIAL HERE....d1lH8MfUyRXmpmnNxJHAC2F73IyN
ZmkDb/DRW5onclGzxQITBFP3S6JXd4LNESJcTp705ec1cQ9Wp2Kl+nKrKyv1E5Xx
DQIDAQAB
-----END PUBLIC KEY-----
  </Value>
</PublicKey>

<PublicKey> 要素の子要素。署名付きの JWT の署名を検証するために使用する公開鍵を指定します。ref 属性を使用して鍵をフロー変数に渡すか、PEM でエンコードされた鍵を直接指定します。

デフォルト 該当なし
要否 省略可。非対称アルゴリズムで署名された JWT を検証するには、<Certificate><JWKS> または <Value> 要素を使用して公開鍵を指定する必要があります。
文字列
有効な値 フロー変数または文字列。

<RequiredClaims>

<VerifyJWT name='VJWT-1'>
  ...
  <!-- Directly specify the names of the claims to require -->
  <RequiredClaims>sub,iss,exp</RequiredClaims>

  -or-

  <!-- Specify the claim names indirectly, via a context variable -->
  <RequiredClaims ref='claims_to_require'/>
  ...
</VerifyJWT>

<RequiredClaims> 要素は省略可能です。JWT の検証時に JWT ペイロードに存在する必要があるクレーム名のカンマ区切りのリストを指定します。この要素により、提示された JWT に必要なクレームが含まれるようになりますが、クレームの内容は検証されません。リストされたクレームのいずれも存在しない場合、VerifyJWT ポリシーは実行時にエラーをスローします。

デフォルト 該当なし
要否 省略可
文字列
有効な値 クレーム名のカンマ区切りのリスト。

<SecretKey>

<SecretKey encoding="base16|hex|base64|base64url" >
  <Value ref="private.your-variable-name"/>
</SecretKey>
  

SecretKey 要素は省略可能です。対称(HS*)アルゴリズムを使用する署名付き JWT を検証する場合、または鍵の暗号化に対称(AES)アルゴリズムを使用する暗号化された JWT を検証するときに使用する秘密鍵を指定します。

<SecretKey> の子

次の表に、<SecretKey> の子要素と属性の説明を示します。

要否 説明
エンコード(属性) 省略可

参照される変数での鍵のエンコード方法を指定します。デフォルトでは、encoding 属性が存在しない場合、鍵のエンコードは UTF-8 として扱われます。この属性で有効な値は、hex、base16、base64、base64url です。エンコード値の hex と base16 は同義です。


<SecretKey encoding="hex" >
  <Value ref="private.secretkey"/>
</SecretKey>

上記の例では、エンコードが hex であるため、変数 private.secretkey の内容が 494c6f766541504973 の場合、鍵は 9 バイトのセットとしてデコードされ、その 16 進数は 49 4c 6f 76 65 41 50 49 73 になります。

値(要素) 必須

エンコードされた秘密鍵。ペイロードの検証に使用される秘密鍵を指定します。private.secret-key などの変数で間接的に鍵を指定するには、ref 属性を使用します。


<SecretKey>
  <Value ref="private.my-secret-variable"/>
</SecretKey>

Apigee は、HS256 / HS384 / HS512 アルゴリズムに対して最小限の鍵強度を適用します。鍵の最小長は、HS256 で 32 バイト、HS384 で 48 バイト、HS512 で 64 バイトです。強度の低い鍵を使用すると実行時エラーが発生します。

<Source>

<Source>jwt-variable</Source>

ポリシー構成に含める場合は、検証対象の JWT が存在すると予想されるフロー変数を指定します。

この要素を使用して、フォームまたはクエリ パラメータ変数やその他の変数から JWT を取得するようにポリシーを構成できます。この要素が存在する場合、ポリシーは存在する可能性のある Bearer 接頭辞を削除しません。変数が存在しない場合、またはポリシーが指定された変数で JWT を見つけられない場合、ポリシーはエラーを返します。

デフォルトでは、<Source> 要素が存在しない場合、ポリシーは変数 request.header.authorization を読み取り、Bearer 接頭辞を削除することで JWT を取得します。Authorization ヘッダーで JWT を署名なしトークンとして(Bearer 接頭辞付きで)渡す場合は、ポリシー構成で <Source> 要素を指定しないでください。たとえば、次のように Authorization ヘッダーで JWT を渡す場合は、ポリシー構成で <Source> 要素は使用されません。

curl -v https://api-endpoint/proxy1_basepath/api1 -H "Authorization: Bearer eyJhbGciOiJ..."
デフォルト request.header.authorization(デフォルトに関する重要な情報については上記の注を参照)。
要否 省略可
文字列
有効な値 Apigee フロー変数名。

<Subject>

<Subject>subject-string-here</Subject>
-or-
<Subject ref='variable-containing-subject'/>

このポリシーでは、JWT のサブジェクトがポリシー構成で指定された文字列と一致していることを確認します。このクレームは、JWT のサブジェクトについての識別、またはステートメント作成を行います。これは、RFC7519 に記載されている標準的な一連のクレームの一つです。

デフォルト 該当なし
要否 省略可
文字列
有効な値 サブジェクトを一意に識別する任意の値

<TimeAllowance>

<TimeAllowance>120s</TimeAllowance>

「猶予期間」を示します。たとえば、猶予期間を 60 秒に指定した場合、有効期限切れの JWT でも期限切れの後 60 秒間は有効として扱われます。not-before-time も同様に評価されます。デフォルトは 0 秒(猶予期間なし)です。

デフォルト 0 秒(猶予期間なし)
要否 省略可
文字列
有効な値 値、または値を含むフロー変数への参照。期間は次のように指定できます。
  • s = 秒
  • m = 分
  • h = 時
  • d = 日

<Type>

<Type>type-string-here</Type>

署名付き JWT または暗号化された JWT をポリシーで検証する方法を説明します。<Type> 要素は省略可能です。このポリシーを使用して、ポリシーで JWT が署名付きの JWT と暗号化された JWT のどちらを生成するかを構成リーダーに通知できます。

  • <Type> 要素が存在する場合:
    • <Type> の値が Signed の場合、ポリシーは署名付き JWT を検証します。<Algorithm> 要素は必須です。
    • <Type> の値が Encrypted の場合、ポリシーは暗号化された JWT を検証します。<Algorithms> 要素は必須です。
  • <Type> 要素が存在しない場合:
    • <Algorithm> 要素が存在する場合、ポリシーによって <Type>Signed とみなされます。
    • <Algorithms> 要素が存在する場合、ポリシーによって <Type>Encrypted とみなされます。
  • <Algorithm><Algorithms> も存在しない場合、構成は無効になります。
デフォルト 該当なし
要否 省略可
文字列
有効な値 Signed または Encrypted を指定します。

フロー変数

Verify JWT ポリシーと Decode JWT ポリシーは、成功すると次のパターンに従ってコンテキスト変数を設定します。

jwt.{policy_name}.{variable_name}

たとえば、ポリシー名が jwt-parse-token の場合、ポリシーは JWT で指定されたサブジェクトをコンテキスト変数 jwt.jwt-parse-token.decoded.claim.sub に保存します。(下位互換性を確保するため、jwt.jwt-parse-token.claim.subject でも利用できます)。

変数名 説明
claim.audience JWT オーディエンス クレーム。この値は、文字列または文字列の配列です。
claim.expiry 有効期限の日時を示すエポックミリ秒。
claim.issuedat トークンの発行日を示すエポックミリ秒。
claim.issuer JWT 発行元クレーム。
claim.notbefore JWT に nbf クレームが含まれている場合、この変数に値(エポックミリ秒)が含まれます。
claim.subject JWT サブジェクト クレーム。
claim.name ペイロードに含まれる名前付きクレームの値(標準または追加)。ペイロードに含まれるすべてのクレームに、これらのいずれかが設定されます。
decoded.claim.name ペイロードに含まれる名前付きクレーム(標準または追加)の JSON 解析可能な値。ペイロードに含まれるすべてのクレームに 1 つの変数が設定されます。たとえば、decoded.claim.iat を使用して JWT の発行時刻(エポック秒)を取得できます。claim.name フロー変数を使用することもできますが、クレームへのアクセスにはこの変数を使用することをおすすめします。
decoded.header.name ペイロードに含まれるヘッダーの JSON 解析可能な値。ペイロードに含まれるすべてのヘッダーに 1 つの変数が設定されます。header.name フロー変数を使用することもできますが、ヘッダーへのアクセスにはこの変数を使用することをおすすめします。
expiry_formatted 人間が読める文字列で表された有効期限の日時。例: 2017-09-28T21:30:45.000+0000
header.algorithm JWT で使用される署名アルゴリズム。たとえば、RS256、HS384 など。詳細については、(アルゴリズム)ヘッダー パラメータをご覧ください。
header.kid 鍵 ID(JWT の生成時に追加された場合)。JWT を検証するため、JWT ポリシーの概要の「JSON Web Key Set(JWKS)の使用」もご覧ください。詳細については、(鍵 ID)ヘッダー パラメータをご覧ください。
header.type JWT に設定されます。
header.name 名前付きヘッダーの値(標準または追加)。このいずれかが、JWT のヘッダー部分のすべての追加ヘッダーに設定されます。
header-json JSON 形式のヘッダー。
is_expired true または false
payload-claim-names JWT でサポートされるクレームの配列。
payload-json
JSON 形式のペイロード。
seconds_remaining トークンが期限切れになるまでの秒数。トークンが期限切れの場合、この数値は負の値になります。
time_remaining_formatted トークンが期限切れになるまでの残り時間(人間が読める形式の文字列)。例: 00:59:59.926
valid VerifyJWT では、署名が検証済みであり、現在時刻がトークンの有効期限よりも前で、notBefore トークンの値よりも後の場合、この変数は true になります。それ以外は、false になります。

DecodeJWT では、この変数は設定されません。

エラー リファレンス

このセクションでは、このポリシーによってエラーがトリガーされたときに返される障害コードとエラー メッセージ、Apigee によって設定される障害変数について説明します。これは、障害に対処する障害ルールを作成するうえで重要な情報です。詳細については、ポリシーエラーについて知っておくべきこと障害の処理をご覧ください。

ランタイム エラー

このエラーは、ポリシーの実行時に発生することがあります。

障害コード HTTP ステータス 発生条件
steps.jwt.AlgorithmInTokenNotPresentInConfiguration 401 検証ポリシーに複数のアルゴリズムがある場合。
steps.jwt.AlgorithmMismatch 401 Generate ポリシーで指定されたアルゴリズムが、Verify ポリシーで想定されているアルゴリズムと一致しない場合。指定されたアルゴリズムが一致している必要があります。
steps.jwt.FailedToDecode 401 ポリシーで JWT をデコードできなかった場合。JWT が破損している可能性があります。
steps.jwt.GenerationFailed 401 ポリシーで JWT を生成できなかった場合。
steps.jwt.InsufficientKeyLength 401 HS256 アルゴリズムで鍵が 32 バイト未満の場合、HS386 アルゴリズムで鍵が 48 バイト未満の場合、HS512 アルゴリズムで鍵が 64 バイト未満の場合。
steps.jwt.InvalidClaim 401 クレームが欠落しているか、一致していない場合。または、ヘッダーが欠落しているか、一致していない場合。
steps.jwt.InvalidConfiguration 401 <Algorithm> 要素と <Algorithms> 要素の両方が存在する場合。
steps.jwt.InvalidCurve 401 鍵で指定された曲線が、楕円曲線アルゴリズムでは無効な場合。
steps.jwt.InvalidIterationCount 401 暗号化された JWT で使用された反復回数が、VerifyJWT ポリシーの構成で指定された反復回数と一致していない場合。これは、<PasswordKey> を使用する JWT にのみ適用されます。
steps.jwt.InvalidJsonFormat 401 ヘッダーまたはペイロードで無効な JSON が検出された場合。
steps.jwt.InvalidKeyConfiguration 401 <PublicKey> 要素の JWKS が無効です。理由としては、Apigee インスタンスから JWKS URI エンドポイントに到達できないことが考えられます。パススルー プロキシを作成し、JWKS エンドポイントをターゲットとして使用して、エンドポイントとの接続をテストします。
steps.jwt.InvalidSaltLength 401 暗号化された JWT で使用されたソルトの長さが、VerifyJWT ポリシーの構成で指定されたソルトの長さと一致していない場合。これは、<PasswordKey> を使用する JWT にのみ適用されます。
steps.jwt.InvalidPasswordKey 401 指定した鍵が要件を満たしていない場合。
steps.jwt.InvalidPrivateKey 401 指定した鍵が要件を満たしていない場合。
steps.jwt.InvalidPublicKey 401 指定した鍵が要件を満たしていない場合。
steps.jwt.InvalidSecretKey 401 指定した鍵が要件を満たしていない場合。
steps.jwt.InvalidToken 401 JWT 署名の検証で不合格だった場合。
steps.jwt.JwtAudienceMismatch 401 トークンの検証でオーディエンス クレームが不合格だった場合。
steps.jwt.JwtIssuerMismatch 401 トークンの検証で発行元クレームが不合格だった場合。
steps.jwt.JwtSubjectMismatch 401 トークンの検証でサブジェクト クレームが不合格だった場合。
steps.jwt.KeyIdMissing 401 Verify ポリシーが公開鍵のソースとして JWKS を使用しているが、署名付き JWT のヘッダーに kid プロパティが含まれてない場合。
steps.jwt.KeyParsingFailed 401 指定された鍵情報で公開鍵を解析できない場合。
steps.jwt.NoAlgorithmFoundInHeader 401 JWT にアルゴリズム ヘッダーが含まれていない場合。
steps.jwt.NoMatchingPublicKey 401 Verify ポリシーが JWKS を公開鍵のソースとして使用するが、署名付き JWT の kid は JWKS にリストされない場合。
steps.jwt.SigningFailed 401 GenerateJWT で、HS384 または HS512 アルゴリズムの鍵が最小サイズより小さい場合。
steps.jwt.TokenExpired 401 ポリシーが期限切れのトークンを検証しようとしている場合。
steps.jwt.TokenNotYetValid 401 トークンがまだ有効になっていない場合。
steps.jwt.UnhandledCriticalHeader 401 crit ヘッダーの Verify JWT ポリシーで見つかったヘッダーが KnownHeaders にリストされていない場合。
steps.jwt.UnknownException 401 不明な例外が発生した場合。
steps.jwt.WrongKeyType 401 鍵のタイプが正しくない場合。たとえば、楕円曲線アルゴリズムで RSA 鍵を指定した場合や、RSA アルゴリズムで曲線鍵を指定した場合など。

デプロイエラー

以下のエラーは、このポリシーを含むプロキシをデプロイするときに発生することがあります。

エラー名 原因 修正
InvalidNameForAdditionalClaim <AdditionalClaims> 要素の子要素 <Claim> で使用されているクレームの型が登録済みの名前(kidisssubaudiatexpnbfjti)のいずれかである場合、デプロイが失敗します。
InvalidTypeForAdditionalClaim <AdditionalClaims> 要素の子要素 <Claim> で使用されているクレームが stringnumberbooleanmap 型でない場合、デプロイが失敗します。
MissingNameForAdditionalClaim <AdditionalClaims> 要素の子要素 <Claim> でクレームの名前が指定されていない場合、デプロイが失敗します。
InvalidNameForAdditionalHeader このエラーは、<AdditionalClaims> 要素の子要素 <Claim> で使用されているクレームの名前が alg または typ の場合に発生します。
InvalidTypeForAdditionalHeader <AdditionalClaims> 要素の子要素 <Claim> で使用されているクレームの型が stringnumberbooleanmap 型でない場合、デプロイが失敗します。
InvalidValueOfArrayAttribute このエラーは、<AdditionalClaims> 要素の子要素 <Claim> 内の配列属性の値が true または false に設定されていない場合に発生します。
InvalidValueForElement <Algorithm> 要素に指定された値がサポートされていない場合、デプロイが失敗します。
MissingConfigurationElement このエラーは、<PrivateKey> 要素が RSA ファミリー アルゴリズムで使用されていない場合や、<SecretKey> 要素が HS ファミリー アルゴリズムで使用されていない場合に発生します。
InvalidKeyConfiguration 子要素 <Value><PrivateKey> 要素または <SecretKey> 要素で定義されていない場合、デプロイが失敗します。
EmptyElementForKeyConfiguration <PrivateKey> 要素または <SecretKey> 要素の子要素 <Value> の ref 属性が空か、指定されていない場合、デプロイが失敗します。
InvalidConfigurationForVerify このエラーは、<Id> 要素が <SecretKey> 要素内で定義されている場合に発生します。
InvalidEmptyElement このエラーは、Verify JWT ポリシーの <Source> 要素が空の場合に発生します。存在する場合、Apigee フロー変数名で定義する必要があります。
InvalidPublicKeyValue <PublicKey> 要素の子要素 <JWKS> で使用されている値が、RFC 7517 で指定されている有効な形式になっていない場合、デプロイが失敗します。
InvalidConfigurationForActionAndAlgorithm <PrivateKey> 要素が HS ファミリー アルゴリズムで使用されている場合、または <SecretKey> 要素が RSA ファミリー アルゴリズムで使用されている場合、デプロイが失敗します。

障害変数

ランタイム エラーが発生すると、次の変数が設定されます。詳細については、ポリシーエラーについて知っておくべきことをご覧ください。

変数 説明
fault.name="fault_name" fault_name は、上記のランタイム エラーの表に記載されている障害の名前です。障害名は、障害コードの最後の部分です。 fault.name Matches "InvalidToken"
JWT.failed 障害の場合、すべての JWT ポリシーで同じ変数が設定されます。 JWT.failed = true

エラー レスポンスの例

JWT ポリシーの障害コード

ベスト プラクティスとして、エラー処理では、エラー レスポンスの errorcode の部分をトラップすることをおすすめします。faultstring のテキストには依存しないでください。この部分は変更される可能性があります。

障害ルールの例

    <FaultRules>
        <FaultRule name="JWT Policy Errors">
            <Step>
                <Name>JavaScript-1</Name>
                <Condition>(fault.name Matches "InvalidToken")</Condition>
            </Step>
            <Condition>JWT.failed=true</Condition>
        </FaultRule>
    </FaultRules>