Table of Contents
private_key_jwt はクライアント認証方式のひとつです。OpenID Connect Core 1.0, 9. Client Authentication にて定義されています。
トークンリクエストにおいて、クライアントはデジタル署名された JWT 形式のアサーションを生成し、リクエストに含めます。そして認可サーバーは、そのアサーションの署名とペイロードを検証し、クライアント認証を行います。
認可サーバーは、private_key_jwt 方式を用いたクライアント認証の処理を、Authlete に移管することができます。本記事ではこの方式の概要と、Authlete の設定手順について説明します。
本機能は Authlete 2.0 以降でのみ利用可能になります。
アサーションとして送信する 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 の発行日時。 |
認可サーバー側では、リクエストを下記仕様に従って適切に処理することになります。ただし認可サーバーはこれらの処理をすべて Authlete に委譲できる ため、ここでは詳細は割愛します。
本セクションでは private_key_jwt 方式に対応するための設定を説明します。Authlete サービスと、同方式によって認証されるクライアントの、両方の設定が必要です。
管理者コンソールから以下のように設定してください。
タブ | 項目 | 設定内容 |
---|---|---|
認可 | サポートするクライアント認証方式 | PRIVATE_KEY_JWT を有効化 |
クライアントアプリ開発者コンソールにアクセスし、以下のように設定してください。
タブ | 項目 | 設定内容 |
---|---|---|
基本情報 | クライアントタイプ | CONFIDENTIAL |
認可 | クライアント認証方式 | PRIVATE_KEY_JWT |
認可 | アサーション署名アルゴリズム | RS256 , RS384 , RS512 ,ES256 , ES384 , ES512 ,PS256 , PS384 , PS512 のいずれか |
JWK セット | JWK セットの内容 | JWT アサーションの検証に用いる公開鍵 を含む JWK セット |
以下は、認可サーバーのトークンエンドポイントにおいて private_key_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 セット) を生成します。なお本記事では、生成に mkjwk.org を利用しています。
以下は 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"
}
{
"kty": "EC",
"use": "sig",
"crv": "P-256",
"x": "9Yxd2TvwBbgmupZh3bpg3umKihM_FNAk2_uI_-Edv_Q",
"y": "BOUFuyvWoBZ9-RVSeHJLF-L4I3ORv0xbaM1CKCFJr54",
"alg": "ES256"
}
前述のペイロードを含み、かつ上記の秘密鍵により署名された 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 の /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 レスポンスとして、認可サーバーに以下を返却します。(見やすさを考慮し一部改行してあります)
{
"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 に記述されているクライアント認証方式のほか、クライアントアサーションやクライアント証明書を用いるクライアント認証方式についても説明します。