> ## Documentation Index
> Fetch the complete documentation index at: https://developers.authlete.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 「JWT ベースのアクセストークン」の利用

> Authlete における JWT 形式のアクセストークンの有効化方法と追加クレームの指定方法について説明。

<Note>
  This page is for **Authlete 2.x**. For current (3.0) documentation, see [this page](/ja/configuration-reference/tokens-and-claims/using-jwt-based-access-tokens).
</Note>

## 概要

Authlete には JWT 形式のアクセストークンを発行する機能があります。本記事では、この機能を有効化する方法と、アクセストークンに追加のクレームを指定する方法について説明します。

> 本機能は Authlete 2.1 以降で利用可能です。

## 機能の有効化

[サービス設定](/ja/v2/configuration-reference/service-setup/service-settings)
の「JWK セットの内容」に JWK セットドキュメントを登録します。手順については以下の記事をご参照ください。

* [Authlete サービスの JWK セット設定](/ja/configuration-reference/key-management/jwk-set-settings-for-an-authlete-service)

登録後、「トークン」タブに移動し、適切な「アクセストークン署名アルゴリズム」を選択します。たとえば ES256 の署名鍵を登録した場合（上記の記事の例）には、「ES256」を選択します。

<img src="https://mintcdn.com/authlete/NmFoIJ4VSX_LOgob/img/kb/ja/oauth-and-openid-connect/access-tokens/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2019-12-17_17.43.10.png?fit=max&auto=format&n=NmFoIJ4VSX_LOgob&q=85&s=1339131a290743168d7fe2f85380f6b5" alt="スクリーンショット_2019-12-17_17" width="1172" height="1760" data-path="img/kb/ja/oauth-and-openid-connect/access-tokens/スクリーンショット_2019-12-17_17.43.10.png" />

設定後、Authlete の発行するアクセストークンは JWT 形式となります。

## 追加のプロパティをアクセストークンに埋め込む

任意の Key/Value の組をアクセストークンに埋め込むには 2 つの方法があります。

1. Extra Properties 機能を利用して文字列の値を追加する
2. jwtAtClaims パラメーターを利用して任意のクレームを追加する

それぞれの方法について、概要を以下に示します。

> jwtAtClaims パラメーターは Authlete 2.3 以降で利用可能です。

## 1. Extra Properties 機能を利用して文字列の値を追加する

[Extra Properties](/ja/configuration-reference/tokens-and-claims/how-to-add-extra-properties-to-an-access-token)
を用いると、認可サーバーは任意のプロパティをアクセストークンや認可コードに関連づけることができます。この機能を JWT 形式のアクセストークンに用いると、関連付けたプロパティのうち、クライアントに開示されるよう指定した（"hidden":false の）ものが、カスタムクレームとしてアクセストークンに含まれます。リソースサーバーはこれらのクレームを抽出して利用できるようになります。

### 動作例

以下は、JWT 形式のアクセストークンを発行するよう Authlete サービスを設定した場合の /auth/token API の動作例です。またこの例では Extra Properties を用いた場合の出力を示しています（一部折り返しています）。

"jwtAccessToken" の値、ならびに "responseContent" （トークンレスポンスの内容）の値に含まれる "access\_token" の値が JWS signed JWT になっています。

* リクエスト

```
POST https://eaxample.authlete.com/api/auth/token
Authorization: {{API_Key/API_SECRET}}
Content-Type: application/json
{
  "clientId":"...",
  "clientSecret":"...",
  "parameters":
    "grant_type=authorization_code&
     redirect_uri=https://client.example.org/cb/example.com&
     code=..."
}
```

* レスポンス

```
{
    "type": "tokenResponse",
    "resultCode": "A050001",
    "resultMessage": "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
    "accessToken": "xx2...AFQ",
    "accessTokenDuration": 86400,
    "accessTokenExpiresAt": 1591690046802,
    "action": "OK",
    "clientId": 17201083166161,
    "clientIdAliasUsed": false,
    "grantType": "AUTHORIZATION_CODE",
    **"jwtAccessToken": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ. \
    eyJleGFtcGxlX3BhcmFtZXRlciI6ImV4YW1wbGVfdmFsdWUiLCJz \
    dWIiOiJ0ZXN0dXNlcjAxIiwic2NvcGUiOm51bGwsImlzcyI6Imh0 \
    dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTkxNjkwMDQ2LCJp \
    YXQiOjE1OTE2MDM2NDYsImNsaWVudF9pZCI6IjE3MjAxMDgzMTY2 \
    MTYxIiwianRpIjoieHgycnNJODBER1Z4bHFLdTFQV2R4eWJSLTdB \
    eTZWamJNcTAxY3dNYkFGUSJ9. \
    -9RsKUSnJHmdqNtNpWbbbTah1YxTkicsabIgxrLWHtGiLsTIaEj_ \
    q39AvKYWrmfnw5y0dfaD3qtTScxI94OSIg",**    "properties": [
        {
            "hidden": false,
            "key": "example_parameter",
            "value": "example_value"
        }
    ],
    "refreshToken": "4rA7H1uRZkCQ7Yd0PN98h7IUqW7zT8p1a_BAg0jEyow",
    "refreshTokenDuration": 864000,
    "refreshTokenExpiresAt": 1592467646802,
    "responseContent": "{**"access_token": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ. \
    eyJleGFtcGxlX3BhcmFtZXRlciI6ImV4YW1wbGVfdmFsdWUiLCJz \
    dWIiOiJ0ZXN0dXNlcjAxIiwic2NvcGUiOm51bGwsImlzcyI6Imh0 \
    dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTkxNjkwMDQ2LCJp \
    YXQiOjE1OTE2MDM2NDYsImNsaWVudF9pZCI6IjE3MjAxMDgzMTY2 \
    MTYxIiwianRpIjoieHgycnNJODBER1Z4bHFLdTFQV2R4eWJSLTdB \
    eTZWamJNcTAxY3dNYkFGUSJ9. \
    -9RsKUSnJHmdqNtNpWbbbTah1YxTkicsabIgxrLWHtGiLsTIaEj_ \
    q39AvKYWrmfnw5y0dfaD3qtTScxI94OSIg", \**    "refresh_token":"4rA7H1uRZkCQ7Yd0PN98h7IUqW7zT8p1a_BAg0jEyow",
        "example_parameter": "example_value",
        "scope": null,
        "token_type": "Bearer",
        "expires_in": 86400}",
    "subject": "testuser01"
}
```

上記の JWT アクセストークンの、ヘッダーとペイロードは以下の通りです。ペイロードには Extra Properties (**"example\_parameter":"example\_value"**) が含まれています。

* ヘッダー

```
{
    "kid": "1",
    "alg": "ES256"
}
```

* ペイロード

```
{
    **"example_parameter": "example_value",**    "sub": "testuser01",
    "scope": null,
    "iss": "https://authlete.com",
    "exp": 1591690046,
    "iat": 1591603646,
    "client_id": "17201083166161",
    "jti": "xx2rsI80DGVxlqKu1PWdxybR-7Ay6VjbMq01cwMbAFQ"
}
```

## 2. jwtAtClaims パラメーターを利用して任意のクレームを追加する

jwtAtClaims リクエストパラメーターを用いると、JSON オブジェクトを JWT アクセストークンのクレームとして追加できます。このパラメーターは下記の Authlete API へのリクエスト時に利用可能です。

* [/auth/authorization/issue](/api-reference/authorization-endpoint/issue-authorization-response)
* [/auth/token/issue](/api-reference/token-endpoint/issue-token-response)
* [/auth/token/create](/api-reference/token-operations/create-access-token)
* [/backchannel/authentication/complete](/api-reference/ciba/complete-backchannel-authentication)
* [/device/complete](/api-reference/device-flow/complete-device-authorization)

jwtAtClaims に指定する値の形式は JSON オブジェクトです。jwtAtClaims に指定された JSON オブジェクト内のプロパティ群が、JWT アクセストークンのペイロード部に追加されます。

### 動作例

以下は、[/auth/authorization/issue](/api-reference/authorization-endpoint/issue-authorization-response)
API へのリクエストのパラメーターのひとつに jwtAtClaims を用いる例です。

```
POST https://eaxample.authlete.com/api/auth/authorization/issue
Authorization: {{API_Key/API_SECRET}}
Content-Type: application/json
{
    "ticket": "{{ticket}}",
    "subject": "abc",
    **"jwtAtClaims": "{\"realm\_access\": {\"roles\":[\"A\", \"B\"]}}"**    ...
}
```

この結果、生成される JWT アクセストークンは、以下のようになります。

```
{
    "sub": "abc",
    "iss": "https://example.authlete.com",
    **"realm_access": {
        "roles": [
            "A",
            "B"
        ]
    },**    ...
}
```

### JWT ベースのアクセストークンと識別子型アクセストークンの関係

Authlete のトークン発行エンドポイントでは、アクセストークンの発行に成功した場合、ユーザーに応答する responseContent のほかに、以下のプロパティが応答されます。

* accessToken
* jwtAccessToken (JWT ベースのトークンが発行するよう構成されている場合、responseContent の access\_token と同一)

認可サーバーは上記のレスポンスから自由にトークンレスポンスを作成いただけます。例えば responseContent の JSON に独自の識別子型アクセストークンを含むプロパティを追加し両方のトークンを応答する、クライアントごとに accessToken か jwtAccessToken のいずれかを応答するといった実装も可能です。

また JWT ベースのアクセストークンに含まれる jti クレームは Authlete の識別子型アクセストークンの値と一致します。

### JWT ベースのアクセストークンの失効確認

JWT ベースのアクセストークンはトークンの失効確認に認可サーバーへの問い合わせが不要な点が大きなメリットですが、特殊なシナリオでは JWT ベースのアクセストークンについても失効、失効確認を行いたい場合があります。例えば、通常はパフォーマンスを重視し JWT ベースのアクセストークンでトークンの検証を行い、重要な操作時には認可サーバーでの失効状況もチェックする、といった特別な要件を満たすようなシナリオがあるかもしれません。

Authlete サーバーが発行した JWT ベースのトークンの失効を実装したい場合、Authlete 固有の動作について理解する必要があります。

#### JWT ベースのアクセストークンを失効する方法

Authlete の失効エンドポイント (/auth/revocation) は JWT 型のアクセストークンに直接対応はしておらず、JWT 型アクセストークンを直接提示しても失効ができません。
JWT アクセストークンを失効 (Authlete 内部のデータベース内で失効) したい場合には、ペイロードの jti クレームに含まれる識別子型トークンを失効エンドポイントに送信する必要があります。

```http theme={null}
### 失効不可
POST https://eaxample.authlete.com/api/auth/authorization/revocation
Authorization: {{API_Key/API_SECRET}}
Content-Type: application/json

{
  "parameters": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ....&token_type_hint=access_token",
  "clientId": "...",
  "clientSecret": "..."
}

### 失効可
POST https://eaxample.authlete.com/api/auth/authorization/revocation
Authorization: {{API_Key/API_SECRET}}
Content-Type: application/json

{
  "parameters": "xx2rsI80DGVxlqKu1PWdxybR-7Ay6VjbMq01cwMbAFQ....&token_type_hint=access_token",
  "clientId": "...",
  "clientSecret": "..."
}
```

失効確認については、Authlete 独自のトークンイントロスペクション API (/auth/introspection) では JWT アクセストークンを受け入れ、かつ jti からデータベースレコードもチェックするため、jti クレームをもとに失効処理を行った JWT アクセストークンについては正しく失効確認が行えます。
一方、/auth/introspection/standard では JWT 型アクセストークンの署名と有効期限検証のみを実施し、データベースレコードのチェックは行わないため jti をベースとした失効確認は行いません。

## 参考情報

* [OAuth アクセストークンの実装に関する考察 - Qiita](https://qiita.com/TakahikoKawasaki/items/970548727761f9e02bcd)

  * [5. Authlete の実装](https://qiita.com/TakahikoKawasaki/items/970548727761f9e02bcd#5-authlete-%E3%81%AE%E5%AE%9F%E8%A3%85)

* [JWT-based Access Token](https://speakerdeck.com/takahikokawasaki/authlete-feature-update-2019-03-25?slide=25)
  (slide #25)[](https://speakerdeck.com/takahikokawasaki/authlete-feature-update-2019-03-25?slide=25)

* [com.authlete.common.dto.Service](http://authlete.github.io/authlete-java-common/com/authlete/common/dto/Service.html)
