private_key_jwt によるクライアント認証
はじめに
private_key_jwt はクライアント認証方式のひとつです。OpenID Connect Core 1.0, 9. Client Authentication にて定義されています。
トークンリクエストにおいて、クライアントはデジタル署名された JWT 形式のアサーションを生成し、リクエストに含めます。そして認可サーバーは、そのアサーションの署名とペイロードを検証し、クライアント認証を行います。
認可サーバーは、private_key_jwt 方式を用いたクライアント認証の処理を、Authlete に移管することができます。本記事ではこの方式の概要と、Authlete の設定手順について説明します。

private-key-jwt_ja.png 79.13 KB

private_key_jwt の処理
アサーションとして送信する JWT には署名・ペイロードに関していくつかの要件が定められており、認可サーバー側ではこの検証を行う必要があります。
クライアント側と認可サーバー側に必要となる処理は、それぞれ下記の通りです。
クライアント側の処理
private_key_jwt 方式を用いる場合、クライアントはトークンリクエストに以下のパラメーターを含める必要があります。
client_assertion にはペイロードと署名について以下の要件を満たす JWT を指定します。この JWT の具体例は「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 に委譲できるため、ここでは詳細は割愛します。
- JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (RFC7523)
-
Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants (RFC7521)
Authlete の設定
本セクションでは private_key_jwt 方式に対応するための設定を説明します。Authlete サービスと、同方式によって認証されるクライアントの、両方の設定が必要です。
Authlete サービスの設定
クライアントの設定
クライアントアプリ開発者コンソールにアクセスし、以下のように設定してください。

基本情報タブ 
認可タブ 
JWK セット タブ
タブ |
項目 |
設定内容 |
基本情報 |
クライアントタイプ |
CONFIDENTIAL |
認可 |
クライアント認証方式 |
PRIVATE_KEY_JWT |
認可 |
アサーション署名アルゴリズム |
RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512 のいずれか |
JWK セット |
JWK セットの内容 |
JWT アサーションの検証に用いる公開鍵を含む 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 を利用しています。

以下は 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 ライブラリを利用して 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 リクエスト
$ 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 に記述されているクライアント認証方式のほか、クライアントアサーションやクライアント証明書を用いるクライアント認証方式についても説明します。
How did we do with this article?