---
schema_version: "1"
id: 0843ab07ae453a6770a2096a94cdbf4293efb03ac3aaeee77a7e111ec9ffba1c
title: JWT ライブラリ関数の使用
collection: mulesoft
version: current
locale: ja-jp
portal_url: https://docs.salesforce.com/mulesoft/current/ja-jp/pdk/1.3/policies-pdk-configure-features-jwt.md
canonical_url: https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-jwt
source_site: docs.mulesoft.com
content_type: documentation
content_hash: ba8879785df92e7de02efb2f989265a689c52d2fa50116b9a0f20fd230b227f6
description: MuleSoft Documentation Site
release: "1.3"
latest: false
---
# JWT ライブラリ関数の使用

<table><tbody><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">Flex Gateway ポリシー開発キット (PDK) の JWT ライブラリを使用したポリシープロジェクトの例は、 <a href="https://github.com/mulesoft/pdk-custom-policy-examples/blob/1.2.0/jwt-validation/README.md" target="_blank" rel="noopener">「JWT Validation Policy Example (JWT 検証ポリシーの例)」</a>​を参照してください。</td></tr></tbody></table>

JSON Web Token (JWT) は、2 者間で転送されるクレームを表す URL セキュアな方法です。JWT トークンには、JSON Web Signature (JWS) のペイロードとして、またはプレーンテキストの JSON Web Encryption (JWE) 構造体として JSON オブジェクトでエンコードされたクレームが含まれており、これによりクレームはデジタル署名され、メッセージ認証コード (MAC) で保護されます。トークンは署名されるので、その情報と情報源を信頼できます。

PDK の JWT ライブラリには、JWT シグネチャーを検証し、すべての受信要求のクレームを抽出して検証するためのツールセットが用意されています。

## [](#extract-a-jwt-token)JWT トークンの抽出

PDK は、認証ヘッダーにある ​`Bearer <token>`​ という形式の JWT トークンを抽出するための ​`bearer`​ 関数を持つ ​`TokenProvider`​ 構造体を提供しています。次の例は、​`bearer`​ 関数の使い方を示しています。

```Rust
// [...]
use pdk::jwt::*;
// [...]

async fn filter(
    state: RequestState,
) -> Flow<()> {
    let headers_state = state.into_headers_state().await;

    // Extract token
    let token = TokenProvider::bearer(headers_state.handler())?;
// [...]
```

異なるソースや異なる形式の JWT トークンを使用する場合は、要求の他の部分を取得する Rust ロジックを実装できます。DataWeave パラメーターを使用して抽出を構成し、JWT ソースを動的に変更できるポリシーを作成します。

## [](#signature-validation)JWT トークンの検証

JWT ライブラリは、受信要求の認証トークンの署名検証を実行するためのヘルパーを提供しています。ポリシーで使用されるアルゴリズムに応じて、対応する設定で ​`SignatureValidator`​ を初期化します。

```Rust
pub fn new(algorithm: SigningAlgorithm, key_length: SigningKeyLength, key: String) -> Result<SignatureValidator, JWTError>
```

PDK は以下の署名アルゴリズムとキー長をサポートしています。

<table class="tableblock frame-all grid-all fit-content spread">
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>署名アルゴリズム</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>署名キーの長さ</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>RSA</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>256、384、512</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>HMAC</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>256、384、512</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>ES</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>256、384</p>
</div></div></td>
</tr>
</tbody>
</table>

`SigningAlgorithm`​ 列挙型は、利用可能な署名アルゴリズムを定義します。

```Rust
pub enum SigningAlgorithm {
    Rsa,
    Hmac,
    Es,
}
```

`SigningKeyLength`​ 列挙型は、利用可能な署名キーの長さを定義します。

```Rust
pub enum SigningKeyLength {
    Len256,
    Len384,
    Len512,
}
```

`SignatureValidator`​ インスタンスは ​`SignatureValidation`​ trait を実装します。この ​`SignatureValidation`​ trait は、トークンを​`文字列型`​のパラメーターとして受け取り、解析された ​`JWTClaims`​ を含む​`結果`​を返すか、エラーの場合は ​`JWTError`​ を返す ​`validate`​ 関数を提供します。

```Rust
pub trait SignatureValidation {
    fn validate(&self, token: String) -> Result<JWTClaims, JWTError>;
}
```

次のコード例は、​`SignatureValidator`​ を初期化し、256 バイトの HMAC アルゴリズムで署名された受信トークンを検証する方法を示しています。

```Rust
use anyhow::Result;
use pdk::hl::*;
use pdk::jwt::*;
// [...]

async fn filter(
    state: RequestState,
    signature_validator: &SignatureValidator,
) -> Flow<()> {
    let headers_state = state.into_headers_state().await;

    // Extract token
    let token = TokenProvider::bearer(headers_state.handler())?;

    if token.is_err() {
        return Flow::Break(Response::new(401).with_body("Bearer not found"));
    }

    // Validating signature
    let claims = signature_validator.validate(token.unwrap());

    if claims.is_err() {
        return Flow::Break(Response::new(401).with_body("Invalid token"));
    }
    // [...]
}

#[entrypoint]
async fn configure(launcher: Launcher, Configuration(configuration): Configuration) -> Result<()> {
    let config: Config = serde_json::from_slice(&configuration)?;

    let signature_validator = SignatureValidator::new(
        model::SigningAlgorithm::Hmac,
        model::SigningKeyLength::Len256,
        config.secret.clone(),
    )?;

    launcher
        .launch(on_request(|request| {
            filter(request, &signature_validator)
        }))
        .await?;
    Ok(())
}
```

`SignatureValidator`​ は初期化時にポリシーの設定が正しいことを確認するため、​`#[entrypoint]`​ 関数で ​`SignatureValidator`​ を初期化すると、API が要求を受信したときではなく、ポリシーが適用されたときに早期にエラーがスローされます。

初期化後、ポリシーはラップされた関数の ​`on_request`​ に ​`SignatureValidator`​ を渡し、受信要求に対して ​`validate`​ メソッドを実行します。

## [](#access-claims)クレームへのアクセスとヘッダーへの伝搬

[署名検証](#signature-validation)​の実行後、結果には JWT トークンから解析された JWT クレームが含まれます。

署名が無効な場合、または署名を検証しないことを選択した場合、PDK は ​`JWTClaimsParser`​ によってクレームを解析します。この構造体は、​`Result<JWTClaims, JWTError>`​ を返す ​`parse`​ メソッドを提供します。

```rust
// Being "token" a String that contains a JWT token
let parsed_claims = JWTClaimsParser::parse(token);

if claims.is_err() {
    return Flow::Break(Response::new(401).with_body("Invalid token"));
}
```

署名検証または解析メソッドを実行したら、​`JWTClaims`​ 構造体が提供する以下のメソッドを使用して JWT クレームにアクセスします。

```rust
pub fn audience(&self) -> Option<Result<Vec<String>, JWTError>>

pub fn not_before(&self) -> Option<DateTime<Utc>>

pub fn expiration(&self) -> Option<DateTime<Utc>>

pub fn issued_at(&self) -> Option<DateTime<Utc>>

pub fn issuer(&self) -> Option<String>

pub fn jti(&self) -> Option<String>

pub fn nonce(&self) -> Option<String>

pub fn subject(&self) -> Option<String>

pub fn has_claim(&self, name: &str) -> bool

pub fn get_claim<T>(&self, name: &str) -> Option<T> where T: ValueRetrieval,

pub fn has_header(&self, name: &str) -> bool

pub fn get_header(&self, name: &str) -> Option<String>

pub fn get_claims(&self) -> pdk_script::Value

pub fn get_headers(&self) -> pdk_script::Value
```

提供されているメソッドは、それぞれの標準 JWT クレームを返すように設計されています。

`get_claim`​ メソッドは、標準またはカスタムクレームを返します。​`get_claim`​ は異なる対象変数型をサポートしているため、ユーザーは出力種別を指定する必要があります。 `get_claim`​ は、出力種別として ​`String`​、​`f64`​、​`Vec<String>`​、​`chrono::DateTime<chono::Utc>`​、​`serde_json::Value`​ をサポートしています。クレームがトークン中に存在しない場合に備えて、​`Option`​ で種別をラップする必要があります。例:

```rust
let some_custom_claim: Option<String> = claims.get_claim("username");
```

次の例では、ラップされた関数から JWT トークンを解析し、カスタムクレームを取得して、リクエストヘッダーに伝播する方法を示しています。

```rust
async fn filter(
    state: RequestState,
) -> Flow<()> {

    let headers_state = state.into_headers_state().await;

    // Extract token
    let token = TokenProvider::bearer(headers_state.handler())?;

    if token.is_err() {
        return Flow::Break(Response::new(401).with_body("Bearer not found"));
    }

    // Being "token" a String that contains a JWT token
    let parsed_claims = JWTClaimsParser::parse(token.unwrap());

    if claims.is_err() {
        return Flow::Break(Response::new(401).with_body("Invalid token"));
    }

    let claims = claims.unwrap();

    let username: Option<String> = claims.get_claim("username");

    if let Some(custom_claim) = some_custom_claim {
        headers_state
            .handler()
            .set_header("username", custom_claim.as_str());
    }

    Flow::Continue(())
}
```

## [](#validate-claims)クレームの検証

通常、JWT トークンには、検証可能な標準および非標準クレームが含まれています。JWT トークンのヘッダーまたはペイロードに存在するクレームを取得するには、​[クレームへのアクセスとヘッダーへの伝搬](#access-claims)​ のメソッドを使用します。取得したら、クレームの値を検証します。

次のコード例では、JWT トークンについて以下を検証しています。

- `exp`​ クレームによって期限切れではないことを検証。
- `aud`​ クレームによって正しいオーディエンス値を持っていることを検証。
- DataWeave 式ポリシーパラメーターとして設定されたカスタムバリデーターを使用して、正しいカスタム ​`role`​ クレームを持っていることを検証。

```Rust
use chrono::Utc;
use pdk::hl::*;
use pdk::jwt::*;
use pdk::logger::info;
use pdk::script::Evaluator;

async fn filter(
    state: RequestState,
    mut custom_validator: Evaluator<'_>,
) -> Flow<()> {
    let headers_state = state.into_headers_state().await;
    let token = TokenProvider::bearer(headers_state.handler());

    if token.is_err() {
        return Flow::Break(Response::new(400).with_body("Bearer not found"));
    }

    // Being "token" a String that contains a JWT token
    let parsed_claims = JWTClaimsParser::parse(token.unwrap());

    if claims.is_err() {
        return Flow::Break(Response::new(401).with_body("Invalid token"));
    }

    let claims = claims.unwrap();

    // Validating token expiration
    if let Some(exp) = claims.expiration() {
        if exp < Utc::now() {
            return Flow::Break(Response::new(400).with_body("token expired"));
        }
    } else {
        return Flow::Break(Response::new(400).with_body("token missing exp claim"));
    }

    // Validating audience
    if let Some(aud) = claims.audience() {
         if !aud_value.iter_mut().any(|a| a == "myAudience") {
            return Flow::Break(Response::new(400).with_body("token does not have the expected audience"));
        }
    }

    // Custom claim validation
    custom_validator.bind_vars("claimSet", claims.get_claims());
    let result = custom_validator_role_claim.eval();
    if !result.ok().and_then(|value| value.as_bool()).unwrap_or_default() {
        return Flow::Break(Response::new(400).with_body("custom token validations failed."));
    }

    Flow::Continue(())
}

#[entrypoint]
async fn configure(launcher: Launcher, Configuration(configuration): Configuration) -> Result<()> {
    let config: Config = serde_json::from_slice(&configuration)?;

    launcher
        .launch(on_request(|request| {
            filter(request, config.custom_validator_role.evaluator())
        }))
        .await?;
    Ok(())
}
```

上の例では、​`gcl.yaml`​ スキーマ定義で次のように入力パラメーターとして設定されている DataWeave 式によってカスタム ​`role`​ クレームが定義されています。

```yaml
# [...]
spec:
  extends:
    - name: extension-definition
      namespace: default
  properties:
    customValidatorRole:
      type: string
      format: dataweave
      default: "#[vars.claimSet.role == 'superRole']"
      # [...]
  required:
    - customValidatorRole
```

## [](#関連情報)関連情報

- [Rust でのカスタムポリシー機能の実装](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features)