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

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

はじめに

private_key_jwt はクライアント認証方式のひとつです。OpenID Connect Core 1.0, 9. Client Authentication にて定義されています。

トークンリクエストにおいて、クライアントはデジタル署名された JWT 形式のアサーションを生成し、リクエストに含めます。そして認可サーバーは、そのアサーションの署名とペイロードを検証し、クライアント認証を行います。

認可サーバーは、private_key_jwt 方式を用いたクライアント認証の処理を、Authlete に移管することができます。本記事ではこの方式の概要と、Authlete の設定手順について説明します。
 

private-key-jwt_ja

本機能は Authlete 2.0 以降でのみ利用可能になります。

private_key_jwt の処理

アサーションとして送信する 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 アサーションの生成」のセクションをご覧ください。

ペイロード

下記のうち、必須のクレームを含む必要があります。

クレーム 必須 説明
iss YES この JWT の発行者。値はクライアント ID に一致しなければならない。
sub YES この JWT のサブジェクト。値はクライアント ID に一致しなければならない。
aud YES この JWT の受け取り手。認可サーバーはこの値が適切なものかどうか検証しなければならない。また、この値はトークンエンドポイントの URI であるべきである。
jti YES この JWT の ID。このトークンに固有の識別子であり、再利用を防止するために使うことができる。再利用の条件についてパーティ(組織)間での合意がない場合には、トークンは 1 回しか使用できない (only be used once)。なお合意の詳細については仕様の範囲外である。
exp YES この JWT の有効期限。この値を超えた JWT は受け付けてはならない。
iat NO この JWT の発行日時。

署名

  • 署名は非対称暗号アルゴリズム   (RS256 など) における秘密鍵を用いて計算すること
  • クライアントは事前に署名検証用の公開鍵 を認可サーバーに登録し、認可サーバーがアサーションを検証できるようにしておくこと

認可サーバー側の処理

認可サーバー側では、リクエストを下記仕様に従って適切に処理することになります。ただし認可サーバーはこれらの処理をすべて Authlete に委譲できる ため、ここでは詳細は割愛します。


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 セット
client-auth-private-key-jwt_2
基本情報タブ
client-auth-private-key-jwt_3
認可タブ
client-auth-private-key-jwt_4
JWK セット タブ

実行例

以下は、認可サーバーのトークンエンドポイントにおいて private_key_jwt によるクライアント認証を行う例です。

JWT アサーションの生成

事前準備として、トークンリクエストに含める client_assertion パラメーターの値 (JWT) を生成します。

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 を利用しています。

client-auth-private-key-jwt_5

以下は ES256 を署名アルゴリズムとして利用する場合の秘密鍵・公開鍵の例です。ここでは生成した公開鍵と秘密鍵のペアを “key_pair.jwk” として保存します。

公開鍵(以下の後者のデータ)を、Authlete に、「JWK セットの内容」として登録するのを忘れないようにしてください。また、クライアント認証方式 (PRIVATE_KEY_JWT) およびアサーション署名アルゴリズム (ES256) についても設定が必要です。これらは前節にて示した通り、クライアントアプリ開発者コンソールから設定できます。

  • 公開鍵と秘密鍵のペア
{
    "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 ライブラリ を利用して JWT を生成する例ですが、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://api.authlete.com/api/auth/token \
-H 'Content-Type: application/json' \
-u '...:...' \
-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 のクライアント認証設定の基本を説明します。

認可サーバーは、client_secret_jwt 方式を用いたクライアント認証の処理を、Authlete に移管することができます。本記事ではこの方式の概要と、Authlete の設定手順について説明します。

この記事では、OAuth 2.0 の『クライアント認証 』について説明します。RFC 6749 に記述されているクライアント認証方式のほか、クライアントアサーションやクライアント証明書を用いるクライアント認証方式についても説明します。