このページは Authlete 3.0 用です。2.x についてはこちらのページをご覧ください。
1. イントロダクション
RFC 7636: Proof Key for Code Exchange (PKCE, 「ピクシー」と発音します) は、 認可コード横取り攻撃(authorization code interception attack) への対策に関する仕様です。
- 認可リクエスト:
code_challengeパラメーターとcode_challenge_methodパラメーターを追加 - トークンリクエスト:
code_verifierパラメーターを追加
2. PKCE 認可リクエスト
2.1 リクエストパラメーター
PKCE に対応したクライアントアプリは、認可リクエストにcode_challenge パラメーターを追加し、その値としてコードチャレンジを含めます。
code_challenge_method パラメーターはオプションです。ただし特別な理由がない限りは、コードチャレンジメソッドとして後述する S256 の利用が推奨されています。そのため結果的には、S256 を値として指定するために、code_challenge_method パラメーターも追加することになります。
2.2 コードチャレンジ
クライアントアプリは、コードベリファイアの値にコードチャレンジメソッドの計算ロジックを適用して、コードチャレンジの値を導出します。2.3 コードベリファイア
クライアントアプリが生成しなくてはならないコードベリファイアの値は、[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" からなるランダムな文字列であり、最低43文字、最大128文字の長さが必要となります。

2.4 コードチャレンジメソッド
コードチャレンジメソッドの値としてはplain および S256 が定義されています。それぞれの計算ロジックは下記の通りです。
| Method | Logic |
|---|---|
plain | code_challenge = code_verifier |
S256 | code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) |
plain では、インプットは何ら変換されません。コードベリファイアの値が、そのままコードチャレンジの値となります。
S256 では、SHA-256 のハッシュ値を BASE64-URL エンコードした値を用います。例えば、code_verifier の値が dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk である場合、code_challenge の値は E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM となります。
S256 を用いる場合、クライアントアプリは認可リクエストの中に code_challenge_method=S256 を含める必要があります。 code_challenge_method パラメーターがない場合、認可サーバーは plain が使われていると判断し、処理します。
3. PKCE 認可レスポンス
認可サーバーは認可コードを生成した後、その値と併せて、認可リクエストに含まれているcode_challenge の値と code_challenge_method の値を、データベース上に保存します。
認可サーバーはこれらの値を、その後クライアントアプリから送られてくるトークンリクエストの検証に用います。
認可エンドポイントから返されるレスポンス自体は、これまでと同様であり、PKCE 特有のパラメーター等はありません。

4. PKCE トークンリクエスト
認可サーバーから認可コードを受け取った後、クライアントアプリはトークンリクエストを生成します。トークンリクエストには、認可コードに加え、コードチャレンジの値の元となったコードベリファイアの値を、code_verifier パラメーターの値として含める必要があります。

5. PKCE トークンレスポンス
5.1 コードベリファイアの有無を確認する
PKCE をサポートする認可サーバーは、トークンリクエストに正当なコードベリファイアが含まれているのかを確認します。 この確認は、 grant_type が authorization_code であり、トークンリクエスト中の認可コードがコードチャレンジと紐づいている場合に限ります。 これらの条件がそろっていても、トークンリクエスト中にコードベリファイアが含まれていない場合、そのリクエストは悪意のあるクライアントアプリからのリクエストと認識し、認可サーバーはエラーを返します。5.2 コードベリファイアを検証する
認可サーバーは 2 つのコードチャレンジを照合し、トークンリクエストの正当性を検証します。 コードチャレンジの片方は、認可リクエストに含まれていた(認可サーバーがデータベースに保存しておいた)値です。もう片方は、認可リクエストで指定された方法(トークンチャレンジメソッド)を用いて、トークンリクエスト中のコードベリファイアから計算される値です。 もしこれら 2 つのコードチャレンジが同一の場合、そのトークンリクエストを送信してきたクライアントアプリは、先の認可リクエストの送信元だったクライアントアプリと同一であると、認可サーバーは判断します。一致しない場合、認可サーバーは、そのトークンリクエストが悪意のあるクライアントアプリから来たものと判定します。5.3 トークンを発行する
トークンリクエストが正規の場合、認可サーバーは通常通りトークンを発行します。
6. PKCE を試す
6.1 準備する
6.1.1 サインアップする
Authlete のアカウントをお持ちでない場合は、まず初めにサインアップしてください。6.1.2 サービス API キーとクライアント ID
認可リクエストを実行するためには、サービス API キーと クライアント ID が必要となります。これらはサインアップと同時に発行されています(動作確認用の認可サーバーとクライアントアプリがひとつずつ自動的に生成されています)。 実際の値については、アカウント登録時に送信されるメールの記載や、管理者コンソールおよびクライアントコンソールからご確認ください。6.1.3 サービスとクライアントの設定
認可サーバー(管理者コンソールのサービス)及びクライアントアプリ (クライアントコンソールのアプリ) の設定は下記を参考にしてください。 Table. Settings of Service in Service Owner Console| カテゴリ | パラメーター | 値 |
|---|---|---|
| 認可 | サポートする認可種別 | 少なくとも AUTHORIZATION_CODE にチェックを入れる |
| 認可 | サポートする応答種別 | 少なくとも CODE にチェック入れる |
| 認可 | ダイレクト認可エンドポイントの有効化 | 有効 |
| 認可 | ダイレクトトークンエンドポイントの有効化 | 有効 |
| カテゴリ | パラメーター | 値 |
|---|---|---|
| 基本情報 | クライアントタイプ | PUBLIC を選択する |
| 認可 | 認可種別 | 少なくとも AUTHORIZATION_CODE にチェックを入れる |
| 認可 | 応答種別 | 少なくとも CODE にチェック入れる |
| 認可 | リダイレクト URI | https://api.authlete.com/api/mock/redirection/service-api-key |
6.2. 認可リクエスト・レスポンス
6.2.1. 認可エンドポイントにアクセスする
下記の URL にブラウザからアクセスしてください。その際、service-api-key と client-id は自身のものに置き換えてください。code_challenge と code_challenge_method が、これまで説明してきた PKCE 関連のパラメーターです。コードチャレンジメソッドとして S256 を指定し、コードチャレンジとして、後述するコードベリファイアから計算した値 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw を含めています。
6.2.2 認可リクエスト
認可エンドポイントにおいて、認可ページが表示されます。その中にあるログインフォームに、ここでは動作確認として、ログイン ID としてサービスの API キー、パスワードとして同じく API シークレットを入力し、認可ボタンをクリックしてください。なお、API シークレットの値の確認方法についてはクイックスタートをご参照ください。
6.2.3 認可レスポンス
認可エンドポイントから返されるレスポンスは、ブラウザを介して、クライアントアプリのリダイレクトエンドポイントに送られます。送信先(リダイレクト URI)は、サインアップ時に自動生成された動作確認用のクライアントアプリの情報として、すでに登録されています。実際の送信先はhttps://api.authlete.com/api/mock/redirection/service-api-key になります。
このリダイレクトエンドポイントは、動作確認用に Authlete が用意した実装です。この実装では、認可レスポンスとして受け取った各種パラメーターの値を表示します。たとえば、認可コードを含む認可レスポンスを受け取った場合、リダイレクトエンドポイントはその値を下記のように表示します。

6.3 トークンリクエスト
6.3.1 トークンリクエストフォーム
直前のセクションでも述べましたが、認可レスポンス中に認可コードが含まれている場合、トークンリクエストを送信するためのフォームが表示されます。 そのフォームには、コードベリファイアを入力する欄があります。ここでは、dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk と入力して下さい。

6.3.2. トークンレスポンス
認可コードと入力したコードベリファイアが正しい場合、JSON 形式でアクセストークンが返却されます。6.4. PKCE Configuration
Authlete では、クライアントに対し、PKCE の利用、およびコードチャレンジメソッド S256 の指定を強制するよう設定可能です。詳細は以下の記事をご参照ください。- Knowledge Base / OAuth および OpenID Connect / PKCE (RFC 7636)
- 認可リクエストにおける PKCE 利用の強制化: PKCE を利用するよう、クライアントに強制する設定を説明します。
- 認可リクエストでの PKCE 利用における S256 指定の強制化: コードチャレンジメソッドとして S256 を指定するよう、クライアントに強制する設定を説明します。