private_key_jwt によるクライアント認証

private_key_jwt によるクライアント認証

はじめに

private_key_jwtOpenID Connect Core 1.0, 9. Client Authentication に定義されているクライアント認証方法の1つです。

トークンリクエストでは、クライアントがデジタル署名された JWT アサーションを作成し、リクエストに含めます。その後、認可サーバーがアサーションの署名とペイロードを検証することでクライアントを認証します。

Authlete はクライアント認証方法として private_key_jwt をサポートしており、認可サーバーがこれを有効にすることができます。本記事では、この方法の概要と、Authlete を使用したセットアップ手順について説明します。

private-key-jwt

private_key_jwt の要件

以下のセクションでは、クライアントと認可サーバーの両方に関する詳細を説明します。

クライアント

クライアントが private_key_jwt メソッドを使用する場合、トークンリクエストに以下のパラメーターを含める必要があります。

パラメーター 説明
client_assertion_type client_assertion の種類です。その値は “urn:ietf:params:oauth:client-assertion-type:jwt-bearer ” である必要があります。
client_assertion クライアント認証に関する情報を含む JWT です。これは 秘密鍵を使用してデジタル署名された ものである必要があります。詳細は以下を参照してください。

client_assertion の値は、JWT ペイロードおよび JWT 署名について以下の要件を満たす必要があります。JWT の例は “JWT アサーションの生成” セクションを参照してください。

ペイロード

JWT アサーションには以下の必須クレームを含める必要があります。

クレーム 説明
iss [必須] 発行者。この値には OAuth クライアントの client_id を含める必要があります。
sub [必須] 主体。この値には OAuth クライアントの client_id を含める必要があります。
aud [必須] オーディエンス。この値は、認可サーバーを対象とするオーディエンスとして識別します。認可サーバーは自分がトークンの対象であることを検証する必要があります。オーディエンスは認可サーバーのトークンエンドポイントの URL であるべきです。
jti [必須] JWT ID。トークンの一意識別子で、トークンの再利用を防ぐために使用されます。これらのトークンは、関係者間で再利用条件が交渉されていない限り、一度のみ使用する必要があります。このような交渉は本仕様の範囲外です。
exp [必須] JWT が処理されるべきではない期限切れ時間。
iat [任意] JWT が発行された時間。

署名

  • JWT アサーションは、非対称暗号方式の秘密鍵 (例:RS256)を使用してデジタル署名される必要があります。
  • この認証方法を使用するクライアントは、認可サーバーがアサーションを検証できるよう、事前に 公開鍵 を登録する必要があります。

認可サーバー

認可サーバーは、以下の仕様に基づいてトークンリクエストを処理する必要があります。詳細はここでは省略しますが、これらの操作を認可サーバーから Authlete にオフロードできます

設定方法

このセクションでは、private_key_jwt メソッドを有効にするための設定手順について説明します。Authlete サービスとそのクライアントの両方をこのメソッドで認証できるように構成する必要があります。

サービス設定

Authlete 管理コンソールにログインし、サービス設定 > エンドポイント > トークン に移動します。サポートされるクライアント認証メソッド セクションで PRIVATE_KEY_JWT チェックボックスを有効にします。

client-auth-private-key-jwt_1

クライアント設定

タブ キー
基本設定 クライアントタイプ CONFIDENTIAL
エンドポイント > トークン クライアント認証メソッド PRIVATE_KEY_JWT
エンドポイント > トークン アサーション署名アルゴリズム RS256 , RS384 , RS512 ,ES256 , ES384 , ES512 ,PS256 , PS384 , または PS512
キー管理 > JWK セット JWK セット内容 クライアントの JWT アサーションを検証するために使用される公開鍵を含む JWK セット

クライアント設定 > エンドポイント > トークン に移動し、クライアント認証メソッド セクションでドロップダウンメニューを開き、PRIVATE_KEY_JWT を選択し、アサーション署名アルゴリズム として ES256 を選択します。

変更を保存して更新を適用します。

client-auth-private-key-jwt_2

キー管理 > JWK セット に移動します。JWK セット内容 セクションに JWK セットを入力します。

変更を保存して更新を適用します。

client-auth-private-key-jwt_3

この例では、認可サーバーのトークンエンドポイントで private_key_jwt を使用したクライアント認証を示します。

JWT アサーションの生成

JWT を生成し、トークンリクエスト内の client_assertion の値として使用します。

JWT ペイロードの準備

まず、JSON 形式のペイロードを作成し、「payload.json」として保存します。

{
    "jti": "myJWTId001",
    "sub": "38174623762",
    "iss": "38174623762",
    "aud": "http://localhost:4000/api/auth/token/direct/24523138205",
    "exp": 1536165540,
    "iat": 1536132708
}

JWK セットの準備

次に、署名と検証用の JWK セットを準備します。mkjwk.org を使用して JWK セットを生成します。

client-auth-private-key-jwt_5

生成された ES256 アルゴリズムを使用して作成された例を以下に示します。この公開鍵と秘密鍵のペアは「key_pair.jwk」というファイルに保存されます。

  • 公開鍵と秘密鍵のペア
{
    "kty": "EC",
    "d": "ukQKQexNI8PtEv7SKpqUDnbZ-WkN6HaQqcVrVV8ZWRQ",
    "use": "sig",
    "crv": "P-256",
    "x": "9Yxd2TvwBbgmupZh3bpg3umKihM_FNAk2_uI_-Edv_Q",
    "y": "BOUFuyvWoBZ9-RVSeHJLF-L4I3ORv0xbaM1CKCFJr54",
    "alg": "ES256"
}
  • Authlete に登録する公開鍵(クライアント開発者コンソールを介して登録可能)
{
    "kty": "EC",
    "use": "sig",
    "crv": "P-256",
    "x": "9Yxd2TvwBbgmupZh3bpg3umKihM_FNAk2_uI_-Edv_Q",
    "y": "BOUFuyvWoBZ9-RVSeHJLF-L4I3ORv0xbaM1CKCFJr54",
    "alg": "ES256"
}

JWT の生成

ペイロードを含み、秘密鍵で署名された JWT アサーションを生成します。以下は、authlete-jose ライブラリ を使用した生成手順の例です。または、mkjose.org ウェブサイトを使用することもできます。

bin/jose-generator \
--payload-file payload.json \
--sign \
--signing-alg ES256 \
--jwk-signing-alg-file key_pair.jwk

生成された JWT は次のようになります(表示のため改行を含みます)。

eyJhbGciOiJFUzI1NiJ9.
ewogICJqdGkiOiJteUpXVElkMDAxIiwKICAic3ViIjoiMzgxNzQ2MjM3NjIiL
AogICJpc3MiOiIzODE3NDYyMzc2MiIsCiAgImF1ZCI6Imh0dHA6Ly9sb2NhbG
hvc3Q6NDAwMC9hcGkvYXV0aC90b2tlbi9kaXJlY3QvMjQ1MjMxMzgyMDUiLAo
gICJleHAiOjE1MzYxNjU1NDAsCiAgImlhdCI6MTUzNjEzMjcwOAp9Cg.
YB4gdhWUGRjWEsEbKDs7-G2WFH2oYz7bAEP5AtegHXInkY9ncA2V3IoA6O_HV
QuFxyCRIklrxsMk32MfNF_ABA

この JWT は client_assertion の値としてトークンリクエスト時にクライアントが使用します。

トークンリクエストとレスポンス

クライアントから認可サーバーへのトークンリクエスト

クライアントがアサーションを用いて認可サーバーにトークンリクエストを送信する場合を想定します。(読みやすくするために折りたたみ)

POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=Gw30fMKJBHkcOBSde5awLrMm4ahvgCNM2cFSTUOUflY&
redirect_uri=https://example.com/redirection&
client_assertion_type=
 urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
client_assertion=
 eyJhbGciOiJFUzI1NiJ9.
 ewogICJqdGkiOiJteUpXVElkMDAxIiwKICAic3ViIjoiMzgxNzQ2MjM3NjIiL
 AogICJpc3MiOiIzODE3NDYyMzc2MiIsCiAgImF1ZCI6Imh0dHA6Ly9sb2NhbG
 hvc3Q6NDAwMC9hcGkvYXV0aC90b2tlbi9kaXJlY3QvMjQ1MjMxMzgyMDUiLAo
 gICJleHAiOjE1MzYxNjU1NDAsCiAgImlhdCI6MTUzNjEzMjcwOAp9Cg.
 YB4gdhWUGRjWEsEbKDs7-G2WFH2oYz7bAEP5AtegHXInkY9ncA2V3IoA6O_HV
 QuFxyCRIklrxsMk32MfNF_ABA

認可サーバーから Authlete への API リクエスト

認可サーバーは、リクエスト内容を Authlete の /auth/token API に転送します。(読みやすくするために折りたたみ)

$ curl -s -X POST https://us.authlete.com/api/auth/token \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <SERVICE ACCESS TOKEN>' \
-d '{
  "parameters":"grant_type=authorization_code&
  code=Gw30fMKJBHkcOBSde5awLrMm4ahvgCNM2cFSTUOUflY&
  redirect_uri=https://example.com/redirection&
  client\_assertion\_type= urn:ietf:params:oauth:client-assertion-type:jwt-bearer
  &client\_assertion=eyJhbGciOiJFUzI1NiJ9.
  ewogICJqdGkiOiJteUpXVElkMDAxIiwKICAic3ViIjoiMzgxNzQ2MjM3NjIiL
  AogICJpc3MiOiIzODE3NDYyMzc2MiIsCiAgImF1ZCI6Imh0dHA6Ly9sb2NhbG
  hvc3Q6NDAwMC9hcGkvYXV0aC90b2tlbi9kaXJlY3QvMjQ1MjMxMzgyMDUiLAo
  gICJleHAiOjE1MzYxNjU1NDAsCiAgImlhdCI6MTUzNjEzMjcwOAp9Cg.
  YB4gdhWUGRjWEsEbKDs7-G2WFH2oYz7bAEP5AtegHXInkY9ncA2V3IoA6O\_HV
  QuFxyCRIklrxsMk32MfNF\_ABA"

}'

Authlete から認可サーバーへの API レスポンス

Authlete はリクエストを処理し、認可サーバーに以下のような API レスポンスを返します。(読みやすくするために折りたたみ)

{
   "type": "tokenResponse",
   "resultCode": "A050001",
   "resultMessage": "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
   "accessToken": "ni6uDszfkeR5GH96k3cUjt3R7MHG9-xRbMDObaKGY2A",
   "responseContent": {
      "access_token": "ni6uDszfkeR5GH96k3cUjt3R7MHG9-xRbMDObaKGY2A",
      "refresh_token": "dyzc8D96hSdrCmaPaB75uFiqjWTIWHXq-_OjVN17gAk",
      "scope": null,
      "token_type": "Bearer",
      "expires_in": 3600
   },
   ...
}

認可サーバーからクライアントへのトークンレスポンス

認可サーバーは “responseContent” の値を抽出し、トークンレスポンスとしてクライアントに返します(詳細は省略)。

関連リンク

本記事では、Authlete におけるクライアント認証設定の基本を説明しています。

Authlete は client_secret_jwt をクライアント認証方法としてサポートしており、認可サーバーがこれを有効にすることができます。本記事では、この方法の概要と Authlete を使用したセットアップ手順を説明しています。

本記事では、「OAuth 2.0 クライアント認証 」について解説しています。RFC 6749 に記載されているクライアント認証方法に加えて、クライアントアサーションやクライアント証明書を利用した方法についても説明しています。