Skip to main content
For Authlete 2.x documentation, see 2.x version.

はじめに

このドキュメントでは、Authlete を利用した Financial-grade API Security Profile 1.0 - Part 2: Advanced (以下 FAPI)対応のアイデンティティ・プロバイダーを構築する手順を通じて、同仕様が規定するセキュリティ条項の概要と Authlete の設定方法を紹介します。 手順の実施にあたっては、以下のチュートリアルの実施とナレッジベース記事の通読を行い、 OpenID Connect と Authlete に関する基本的な理解を有していることが必須です。

構成

本チュートリアルでは以下の構成を想定します。 なお、実サービスとして動作するのは、Authlete のコンソールと API だけです。 認可サーバー(OIDC アイデンティティプロバイダー)とリソースサーバーはいずれも実際には存在しませんが、 それぞれのサーバーがクライアント(OIDC リライングパーティ)から認可リクエストやトークンリクエスト、そしてトークンイントロスペクションリクエストを受信したときに、 どのような API リクエストを Authlete に行うかを、curl コマンドを用いて試行します。
Note本チュートリアルでは便宜上、OIDC アイデンティティプロバイダーを「認可サーバー」、同リライングパーティを「クライアント」と表記します。
各サービスの FQDN は以下の通りです。上述の通り認可サーバーとクライアントは存在しませんが、OAuth のフローを説明する上で FQDN が最低限必要となります。

FAPI を用いた API クライアントと API サーバーとの間のやりとり

本ドキュメントでは、FAPI に準拠した以下のトークン授受・利用フローに対応するための設定を行います。

1. 認可リクエスト (Authorization Request)

クライアントはリクエストオブジェクトを用いた認可リクエストを作成・送信する必要があります。 リクエストオブジェクトは値渡し(request パラメーターを使用)もしくは参照渡し(request_uri パラメーターを使用)のいずれかとなります。本ドキュメントでは前者を用います。 また、response_type パラメーターの指定についても FAPI の規定に従う必要があります。 response_type として本ドキュメントでは code id_token を用います。 その他、claims の設定などについては後述します。

2. 認可レスポンス (Authorization Response)

本ドキュメントでは、認可リクエストに response_type=code id_token が指定されることから、フラグメントとして code を返却します。

3. トークンリクエスト (Token Request)

トークンリクエストでは、認可サーバーはクライアントを認証する方法として公開鍵方式を用いる必要があります。 本ドキュメントでは TLS 双方向認証を用います。

4. トークンレスポンス (Token Response)

認可サーバーは、トークンエンドポイントに提示されるクライアント証明書と、発行するアクセストークンとをバインド(ひもづけ)し、トークンレスポンスを返却します。

5. API リクエスト (API Request)

クライアントとリソースサーバーは、TLS 双方向認証を用いてクライアント認証を行った上で、アクセストークンを含む API リクエストを送受信します。 リソースサーバーはクライアント証明書とアクセストークンとのひもづけを検証の上、API レスポンスを返却します。

初期設定

新規 Authlete サービスとそのクライアントの追加

Authlete サービスの追加と FAPI の有効化

Authlete のサービス管理者コンソール https://so.authlete.com/ にログインし、右側の「サービス作成」をクリックします。 するとサービス作成のページが表示されます。「サービス名」と「トークン発行者識別子」を以下に従い入力し、「作成」をクリックします。 確認のダイアログが表示されるので「OK」をクリックします。 サービスを作成すると「APIキー」と「APIシークレット」が自動生成されます。 これらの値は、次にクライアントアプリ開発者コンソールにログインするときのログインID・パスワードとして用いるとともに、 認可サーバーが Authlete API にリクエストを行う際のクレデンシャルとなります。 このサービスの FAPI サポートを有効化しましょう。 下方にある「編集」ボタンをクリックし、内容を編集可能にします。 「認可」タブの設定項目の中に「サポートするプロフィール群」があり、 「FAPI」チェックボックスにチェックが入っていない状態になっているはずです。 ここにチェックを入れて、下方にある「更新」ボタンをクリックします。 確認のダイアログが表示されるので「OK」をクリックします。 次に、再度「編集」ボタンをクリックし、内容を編集可能にします。 「トークン」タブの設定項目の中に「サポートするスコープ」があり、 addressopenid などの既定スコープが表示されているはずです。 この項目の右側にある「スコープ作成」ボタンをクリックすると、スコープ作成のダイアログが表示されます。 ここでは以下の内容のスコープを作成します。

クライアントの追加と基本設定

Authlete のクライアントアプリ開発者コンソール(https://cd.authlete.com/<API キー> 例: https://cd.authlete.com/174381609020)にアクセスし、 ログイン ID として先ほど作成したサービスの「API キー」を、 パスワードとして同じく「API シークレット」を用いてログインします。 ログイン後、右手にある「アプリ作成」をクリックすると、 アプリ作成のページが表示されます。まず「基本情報」タブでは、任意の「クライアント名」を入力し、 クライアントタイプとして 「CONFIDENTIAL」 を選択します。 次に、「基本情報」タブの隣にある「認可」タブをクリックし、「リダイレクト URI」セクションにある「リダイレクト URI 作成」をクリックして、 以下のリダイレクト URI を作成します。 指定後、ページ下方にある「作成」をクリックします。 確認のダイアログが表示されるので「OK」をクリックします。 これにより、サービスへのクライアント情報の登録が完了しました。 自動生成された「クライアント ID」は、 クライアントが認可サーバーにリクエストを行う際の client_id の値として用いられます。 なお、同時に「クライアントシークレット」も生成されていますが、 本チュートリアルでは使いません。 また、そのほか指定した各値が正しく設定されていることも確認しましょう。

初期設定後の動作確認

上記の設定によって Authlete がどのように動作するかを、まず /auth/authorization API を用いて確認します。

非 FAPI スコープに関する認可リクエスト

認可サーバーが、FAPI-RW 対象のスコープが含まれない (scope=openid のみの) 認可リクエストを受信したと仮定し、 /auth/authorization API に対して以下のリクエストを送信します。
すると、以下のようなレスポンス(一部折り返しています)が返却されます。
resultMessage の記述から、scope=openid のように、FAPI 対象ではないスコープの場合には、認可リクエストが Authlete に受け入れられたことがわかります。 それでは、FAPI の対象となるスコープの場合にはどのようになるか、次に試してみます。

FAPI スコープに関する認可リクエスト (1)

認可サーバーが、FAPI 対象のスコープ(payment)を含む認可リクエスト(scope=openid payment)を受信したと仮定し、 /auth/authorization API に対して以下のリクエストを送信します。
すると、以下のようなエラーレスポンスが返却されます。
resultMessage の内容を見ると、response_type=code は許可されていないことがわかります。 これは FAPI の 5.2. Advanced security provisions / 5.2.2. Authorization server
  • shall require
    1. the response_type value code id_token, or
    2. the response_type value code in conjunction with the response_mode value jwt;
とある通り、FAPI では response_type=code id_token か、もしくは response_mode=jwt を指定した上でresponse_type=codeの、どちらかを用いなくてはならないからです。 つまり response_type=code のみの指定は禁止されている(認可サーバーはそのようなレスポンスタイプを受け付けてはならない)のです。

FAPI スコープに関する認可リクエスト (2)

それでは、response_type=code ではなく response_type=code id_token とした認可リクエストの場合にはどうなるでしょうか。 /auth/authorization API に対して以下のリクエストを送信します。
すると以下のような異なるエラーレスポンスが返却されます。
resultMessage の記述から、この場合には、リクエストオブジェクトが必要だとわかります。 これは上述と同じく、FAPI の 5.2. Advanced security provisions / 5.2.2. Authorization server
  • shall only use the parameters included in the signed request object passed via the request or request_uri parameter;
とある通り、FAPI では、認可サーバーはクライアントに対して、リクエストオブジェクトを値渡し(request)ないし参照渡し(request_uri)にて認可リクエストに含めるよう、 要求しなくてはならないからです。 それでは次に、リクエストオブジェクトを用いた認可リクエストを準備してみましょう。

認可リクエストの FAPI 対応

本セクションでは、リクエストオブジェクトを用いた認可リクエストを作成します。

リクエストオブジェクトの設定

リクエストオブジェクトの署名鍵の設定

まず、クライアントがリクエストオブジェクトに署名するための鍵を準備します。 ここでは例として、 mkjwk を用いて、ES256 の鍵ペアを生成し、 2 種類(秘密鍵を含むもの・含まないもの)の鍵セットを生成します。 パラメーターは以下の通り選択・入力しています。 以下は生成された鍵セットの例です。
  • es256_keyset.txt (秘密鍵 "d" の行を含む)
  • es256_keyset_pub.txtes256_keyset.txt から秘密鍵 "d" の行を削除)

クライアント設定の追加

Authlete サービスに、クライアントから受信したリクエストオブジェクトの署名を検証させるためには、 そのクライアントの設定として公開鍵を登録し、さらに署名アルゴリズムを指定する必要があります。 Authlete のクライアントアプリ開発者コンソール(https://cd.authlete.com/<API キー> 例: https://cd.authlete.com/174381609020)にアクセスし、 各タブにおいて以下を設定します。
  • JWK セット」タブ
  • 認可」タブ
上記の設定により、リクエストオブジェクトの署名検証の準備が整いました。

リクエストオブジェクトの生成

ここではリクエストオブジェクトを作成し、認可リクエストを組み立てます。 まず、以下のペイロードを準備します。client_id, nbf, exp の値は適宜変更します。 payload.txt
秘密鍵を用いて Signed JWT を作成します。 以下は mkjose を用いて作成する例です。 各項目を入力・選択し、「生成する」ボタンを押下すると、「結果」の欄に Signed JWT が出力されます。 また、step CLI を用いて作成する場合には以下の例のようになります。
以下は実行結果の例です。この文字列を、認可リクエストの request パラメーターの値として用います。

動作確認

認可サーバーが認可リクエストをクライアントから受信したと仮定し、 Authlete の /auth/authorization API に対して以下のリクエストを送信します。
すると、以下のようなレスポンス(一部折り返しています)が返却されます。
requestMessage の記述から、リクエストが受理されたことがわかります。 そして期待した通り、ticket が返却されています。 認可サーバーはこの ticket の値をログインセッションに格納し、 ユーザー認証と同意確認を行い、そして Authlete の /auth/authorization/issue API を呼び出し、 認可レスポンスの生成を要求することになります。 本ドキュメントの手順では、認可リクエストに response_type=code id_token と指定しています。 よって認可レスポンスは、認可コード code と ID トークン id_token を、 フラグメントとして含むものになります。 認可サーバーがユーザー認証と同意確認を行い、その結果決定したユーザー識別子(subject)が testuser01 であったと仮定し、 /auth/authorization/issue API にリクエストを送信してみましょう。 この subject と、上記の ticket が、API リクエストの引数となります。
すると、以下のようなレスポンス(一部折り返しています)が返却されます。
resultMessage の記述から、現在設定されている(Authlete の既定値である)HS256 が、ID トークンの署名アルゴリズムとして許可されていないことがわかります。 これは FAPI の 8.6. Algorithm considerations
  • shall use PS256 or ES256 algorithms;
とある通り、クライアントと認可サーバーは JWS アルゴリズムとして ES256 もしくは PS256 のどちらかを用いなければならないからです。 本ドキュメントでは、認可サーバーが ID トークンの署名アルゴリズムとして ES256 を用いるように、Authlete を設定してみます。

認可レスポンスの FAPI 対応

ID トークンの署名アルゴリズムの変更

ID トークンの署名鍵の追加

ES256 の鍵セットを生成し、ID トークンの署名に用いる鍵としてサービスに登録するとともに、 クライアント設定として ID トークンの署名アルゴリズムに ES256 を指定します。 手順は Authlete ナレッジベースの以下の記事を参照してください。
Noteこのセクションにて生成する鍵セットは、認可サーバーが ID トークンの署名に用いるためのものです。 一方、先の「リクエストオブジェクトの署名鍵の設定」において生成・登録した鍵セットは、 クライアントから受け取ったリクエストオブジェクトの署名を認可サーバーが検証するためのものです。 両者を混同しないようにご注意ください。
本ドキュメントでは、以下のパラメーターを選択・入力します。 生成された鍵セット(“Keypair set”)を、まずサービスに登録します。 Authlete のサービス管理者コンソール https://so.authlete.com/ にログインし、 設定の「JWK Set (JWK セット)」にある「JWK Set Content (JWK セットの内容)」の項目に追加します。 また同じページの「ID Token Signature Key ID(ID トークン署名キー ID)」の項目に、この Keypair set の kid の値(上記の例では「1」)を入力します。 次に、Authlete のクライアントアプリ開発者コンソール(https://cd.authlete.com/<API キー> 例: https://cd.authlete.com/174381609020)にアクセスし、 ログイン ID として先ほど作成したサービスの「API キー」を、 パスワードとして同じく「API シークレット」を用いてログインします。 ログイン後、「ID トークン」タブにある「ID トークンの署名アルゴリズム」の項目にて、「ES256」を選択します。 この設定により Authlete は、このクライアントに対して ID トークンを発行する際の署名アルゴリズムとして ES256 を用いるようになります。

動作確認

変更後、ticket 生成から再度動作確認を行います。 まず /auth/authorization API を実行します。
この処理結果(一部折り返しています)として ticket が返却されます。
返却された ticketsubject の値を用いて、/auth/authorization/issue API にリクエストを行います。
すると、以下のようなレスポンス(一部折り返しています)が返却されます。
resultMessage の記述から、認可リクエストの処理に成功したことがわかります。また idToken, authorizationCode にそれぞれ値が返却されています。 そして responseContent として、認可サーバーがクライアントに返却する HTTP レスポンスが生成されており、レスポンスのフラグメント部に ID トークンと認可コードが含まれていることがわかります。 この後クライアントは ID トークンを検証し、さらにその中に含まれる c_hash クレームを用いて認可コードを検証したのちに、 認可サーバーにトークンリクエストを送信することになります。そして認可サーバーはそのトークンリクエストを Authlete の /auth/token API に送信し、 アクセストークンを含むトークンレスポンスの生成を要求します。 /auth/token API に対するリクエストは以下の通りです。
すると、以下のようなレスポンス(一部折り返しています)が返却されます。
resultMessage の記述から、コンフィデンシャルクライアントのクライアント認証として、 Authlete の既定値である none は許可されていないことがわかります。 これは FAPI の 5.2 Read and write API security provisions / 5.2.2. Authorization server
  • shall authenticate the confidential client using one of the following methods (this overrides FAPI Security Profile 1.0 - Part 1: Baseline clause 5.2.2-4):
    1. tls_client_auth or self_signed_tls_client_auth as specified in section 2 of MTLS, or
    2. private_key_jwt as specified in section 9 of OIDC;
とある通り、FAPI では RFC 8705 が定義する Mutual TLS for OAuth Client Authentication、もしくは OpenID Connect Core 1.0 が定義する private_key_jwt のどちらかを用いなくてはならないからです。つまり none や、コンフィデンシャルクライアントの場合に広く使われている client_secret_basic は禁止されている(認可サーバーはそのようなクライアント認証を行ってはならない)のです。 本ドキュメントでは後者、かつ PKI Mutual-TLS Method (tls_client_auth) を用いるように Authlete を設定してみます。

トークンリクエストの FAPI 対応

TLS クライアント認証の設定

クライアント認証に「TLS クライアント認証」を用いるように、サービスおよびクライアントの設定を変更します。

サービス側の TLS クライアント認証設定

Authlete のサービス管理者コンソール https://so.authlete.com/ にログインし、 「認可」タブの「トークンエンドポイント」セクションにおいて以下を設定します。

クライアント側の TLS クライアント認証設定

Authlete のクライアントアプリ開発者コンソール(https://cd.authlete.com/<API キー> 例: https://cd.authlete.com/174381609020)にアクセスし、 「認可」タブの「トークンエンドポイント」セクションにおいて以下を設定します。 以上の設定により、Authlete サービスは TLS 双方向認証によるクライアント認証に対応し、かつ上記のクライアントからのトークンリクエストについて、その認証方式を適用することになります。 また認証の際のクライアント識別名として CN=client.example.org, ... を用います。

自己署名証明書の生成

クライアントが自身の認証に用いる証明書を作成します。以下は openssl を用いて作成する例です。
  • 秘密鍵の生成
  • CSR の作成
    • Subject DN として CN=client.example.org, O=Client, L=Chiyoda-ku, ST=Tokyo, C=JP を指定
  • 証明書の作成
本手順にて作成した証明書は以下の通りです。 server.crt
curl コマンドを用いてリクエストを行う際には、上記の内容を 1 行で表現したものを用います。

動作確認

サービス設定とクライアント設定をそれぞれ変更したのちに、以下の手順を実行します。
  1. /auth/authorization API を実行し、レスポンスから ticket の値を取得
  2. /auth/authorization/issue API を実行し、レスポンスから authorizationCode の値を取得
  3. 以下を変更の上、/auth/token API を実行
  • clientCertificate パラメーターを追加し、値としてクライアント証明書を指定する
  • clientSecret パラメーターを削除する(TLS 双方向認証を用いるため不要となります)
以下は /auth/token API に送信するリクエストの例です。
すると、以下のようなレスポンス(一部折り返しています)が返却されます。
resultMessage の記述から、アクセストークンは発行されたものの、未だ設定が不足しているために、 FAPI 仕様上必須である 「Holder of Key」が行われなかったことがわかります。 すなわち、ここまでの手順だけでは、 TLS クライアント証明書をひもづけたアクセストークン発行の処理が行われていないということです。

トークンレスポンスの FAPI 対応

Holder of Key の設定

サービス側のアクセストークン設定

Authlete のサービス管理者コンソール https://so.authlete.com/ にログインし、 「トークン」タブの「アクセストークン」セクションにおいて以下を設定します。

クライアント側のアクセストークン設定

Authlete のクライアントアプリ開発者コンソール(https://cd.authlete.com/<API キー> 例: https://cd.authlete.com/174381609020)にアクセスし、 「基本情報」タブにおいて以下を設定します。 以上により、FAPI 準拠の認可サーバーの設定が完了しました。

設定完了後の実行例

変更後、先と同様の手順により /auth/authorization API/auth/authorization/issue API/auth/token API を実行します。 さらに /auth/introspection API を実行して、最終的に API リクエストに用いられるアクセストークンが、クライアントの TLS クライアント証明書に紐づけられていることを確認します。

認可リクエスト

  • レスポンス(一部折り返しています)

認可レスポンス

  • レスポンス(一部折り返しています)

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

  • レスポンス(一部折り返しています)

API リクエスト

上記手順の結果、アクセストークンとして SUtEVc3Tj3D3xOdysQtssQxe9egAhI4fimexNVMjRyU が生成されています。 この値をリソースサーバーがクライアントから受信したと仮定し、/auth/introspection API を用いて、 このアクセストークンの有効性と、関連する情報の取得を試みます。 この際に、リソースサーバーがクライアントから同時に受け取るであろう、クライアント証明書も併せて API に送信します。
  • レスポンス(一部折り返しています)
これによりリソースサーバーは、クライアントから受信したアクセストークンの有効性を確認し、そのトークンにひもづいている情報を取得することができました。

まとめ

本チュートリアルでは、FAPI に準拠したトークン授受・使用に対応した認可サーバーを構築するための、Authlete の設定を行いました。