OAuth 2.0 クライアント認証

# はじめに

この記事では、OAuth 2.0 の『**クライアント認証**』について説明します。

[RFC 6749](https://tools.ietf.org/html/rfc6749) に記述されているクライアント認証方式のほか、クライアントアサーションやクライアント証明書を用いるクライアント認証方式についても説明します。


# 1. クライアント認証方式

## 1.1. トークンエンドポイント

**認可サーバー**があります。
![client_auth_authorization_server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/55feaeba-ab4f-5a8c-a407-39fd6b077299.png)

認可サーバーから**アクセストークン**の発行を受けたい**クライアントアプリケーション**があります。
![client_auth_client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/dcdc1168-e32b-f488-6030-89fe515c02f6.png)

アクセストークンは、幾つかの例外を除き、認可サーバーの**トークンエンドポイント**から発行されます。そのため、認可サーバーはトークンエンドポイントを用意します。
![client_auth_token_endpoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/44a1581b-5983-2177-5f37-d46e67e1fb58.png)

クライアントアプリケーションは、アクセストークンの発行を受けるために、トークンエンドポイントに**トークンリクエスト**を投げます。
![client_auth_token_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/62f866e3-de7e-5d8d-7a00-e47d68d938fa.png)

認可サーバーは、トークンレスポンスを返します。この応答の中に、アクセストークンが含まれます。
![client_auth_token_response.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/9cdd5d0a-9140-73a9-ba5d-e15ec71761d7.png)


## 1.2. クライアントタイプ

クライアントアプリケーションには、**クライアントタイプ**（[RFC 6749](https://tools.ietf.org/html/rfc6749), [2.1. Client Types](https://tools.ietf.org/html/rfc6749#section-2.1)）という属性があります。
![client_auth_client_type.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/d0a92bd3-a7ad-cbad-9b83-3f0286f37fa8.png)

この属性の値は、**public**（パブリック）もしくは **confidential**（コンフィデンシャル）のどちらかです。
![client_auth_client_types.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/10eaa0d9-5e75-e6d6-e47e-fda9adc61458.png)

クライアントタイプが confidential の場合、
![client_auth_confidential.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/01735f5b-8a7f-bfad-1c27-43f43dcbf24f.png)

トークンエンドポイントにアクセスする際、
![client_auth_at_token_endpoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/05858e2d-4592-0404-2296-46a04ae9127d.png)

**クライアント認証**という手続きが必要になります。これは、クライアントの身元を確認するための処理です。
![client_auth_if_confidential.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/e76af86b-d1b9-9563-aea3-a417e930352f.png)


## 1.3. client_secret_post

昔ながらのクライアント認証の方法では、まず、当該クライアントアプリケーション用の**クライアント ID** と**クライアントシークレット**を認可サーバーが生成し、あらかじめクライアントアプリケーションに渡しておきます。
![client_auth_client_id_and_secret.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/75438da6-f3e7-ddc2-633f-e8bc524444de.png)

クライアントアプリケーションは、トークンリクエストを投げる際、
![client_auth_token_request_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/6833e392-029c-006a-878c-eac7341194e9.png)

トークンリクエストにクライアント ID とクライアントシークレットを含めます。認可サーバーは、トークンリクエストに含まれるクライアント ID とクライアントシークレットをチェックすることで、クライアントの身元を確認することができます。
![client_auth_token_request_with_client_id_and_secret.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/24332880-70d2-22a4-33b9-19f8e6b27933.png)

トークンリクエストにクライアント ID とクライアントシークレットを含める方法で一番分かりやすい方法は、`client_id` および `client_secret` というリクエストパラメーターを使う方法です。
![client_auth_client_secret_post.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/8a796fcf-c427-3e75-69a1-05f79d537c40.png)

このクライアント認証方式には `client_secret_post` という名前が与えられています（[OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html), [9. Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication)）。


## 1.4. client_secret_basic

トークンリクエストにクライアント ID とクライアントシークレットを含めるもう一つの方法は、ベーシック認証（[RFC 7617](https://tools.ietf.org/html/rfc7617)）を使う方法です。

この方法を使う場合、まず、クライアント ID、コロン、クライアントシークレットを連結し、一つの文字列を作ります。
![client_auth_client_secret_basic_raw_string.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/e4fc489a-daaf-6a3c-a0fb-7a6e337b9048.png)


次に、この文字列を BASE64（[RFC 4648](https://tools.ietf.org/html/rfc4648)）でエンコードします。
![client_auth_client_secret_basic_base64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/e7c29406-f959-7c22-66d8-96fc9bdd3adc.png)

そして、出来上がった BASE64 文字列を、トークンリクエストの `Authorization` ヘッダーに埋め込みます。
![client_auth_client_secret_basic_token_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/3f6ceffc-868a-04d1-0813-31b21fda649e.png)

このクライアント認証方式には `client_secret_basic` という名前が与えられています（[OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html), [9. Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication)）。

`client_secret_post` と `client_secret_basic` は、[RFC 6749](https://tools.ietf.org/html/rfc6749), [2.3.1. Client Password](https://tools.ietf.org/html/rfc6749#section-2.3.1) に書かれているクライアント認証方式です。


## 1.5. client_secret_jwt

クライアントシークレットを直接トークンリクエストに含めずとも、クライアントシークレットを持っていることを間接的に証明する方法があります。

まず、何らかのデータを用意します。
![client_auth_client_secret_jwt_data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/a107d1b4-de77-2fc0-ccde-a58e9462b0fa.png)

次に、クライアントシークレットを用いてそのデータに対する署名を生成します。
![client_auth_client_secret_jwt_signature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/cacbbe9e-2ce7-aa3a-8bb2-346f11bdaa6f.png)

そして、そのデータと署名を、トークンリクエストに含めます。
![client_auth_client_secret_jwt_token_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/fb833b0a-71c6-15c4-827a-8b4f7fdfad63.png)

認可サーバーは、その署名を検証することで、トークンリクエストを投げてきたクライアントアプリケーションがクライアントシークレットを持っていることを確認でき、もってクライアント認証とすることができます。
![client_auth_client_secret_jwt_verification.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/f45080ba-768b-43c5-ed0e-270a802ed0dd.png)

ここで用意するデータの形式にはルールがあります。詳細は [RFC 7523](https://tools.ietf.org/html/rfc7523), [2.2. Using JWTs for Client Authentication](https://tools.ietf.org/html/rfc7523#section-2.2) に書かれています。簡単に言うと、`iss` クレームなどを含む JSON です。
![client_auth_client_secret_jwt_payload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/a10e3e01-f82f-28c0-52c2-830947f2477b.png)

この JSON に対する署名は、[RFC 7515](https://tools.ietf.org/html/rfc7515)（JSON Web Signature）に定義されている方法でおこないます。署名の結果、JWT（[RFC 7519](https://tools.ietf.org/html/rfc7519)）が生成されますが、この JWT は、クライアント認証の文脈では**クライアントアサーション**と呼ばれます。

そして、このクライアントアサーションを `client_assertion` リクエストパラメーターの値としてトークンリクエストに含めます。また、同時に、`client_assertion_type` リクエストパラメーターも追加します。`client_assertion_type` の値は、`urn:ietf:params:oauth:client-assertion-type:jwt-bearer` という固定値です。
![client_auth_client_secret_jwt_client_assertion.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/336cb6ed-4c97-731f-ca5c-6a99162befd9.png)

このクライアント認証方式には `client_secret_jwt` という名前が与えられています（[OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html), [9. Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication)）。


## 1.6. private_key_jwt

前節のクライアント認証方式では、クライアントアサーションの署名を生成する際、クライアントシークレットという共有鍵を用いました。一方、クライアントアサーションの署名と検証に非対称鍵を用いる方法もあります。

まず、クライアント側で、秘密鍵と公開鍵の組を生成します。
![client_auth_private_key_jwt_key_pair.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/74de4cda-439c-2eb0-a12b-c6e183c09fd5.png)

そして、何らかの方法で、認可サーバーが公開鍵を参照できるようにしておきます。
![client_auth_private_key_jwt_public_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/e3d78d06-0574-364b-d99f-6db582aba190.png)

トークンリクエストに先立って、クライアントは、[RFC 7523](https://tools.ietf.org/html/rfc7523), [2.2. Using JWTs for Client Authentication](https://tools.ietf.org/html/rfc7523#section-2.2) の仕様に従って JSON データを用意します。
![client_auth_private_key_jwt_payload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/0c71b737-9af8-1361-2876-51ec1039f3d2.png)

そのデータに対して、秘密鍵を用いて署名をおこないます。
![client_auth_private_key_jwt_signature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/5c19ae9b-6e07-0bea-4602-dcf53186e27b.png)

生成されたクライアントアサーションを `client_assertion` リクエストパラメーターの値とし、トークンリクエストをおこないます。
![client_auth_private_key_jwt_token_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/f28a5ede-5df1-29e7-6b57-cae9a30f53af.png)

認可サーバーは、トークンリクエストの中からクライアントアサーションを取り出します。
![client_auth_private_key_jwt_extraction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/573993ca-318c-f3ce-8c6b-2f132c883107.png)

そして、公開鍵を用いてクライアントアサーションの署名検証をおこないます。
![client_auth_private_key_jwt_verification.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/35719ab8-1f1a-1651-c974-4fcd5af03477.png)

このクライアント認証方式には `private_key_jwt` という名前が与えられています（[OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html), [9. Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication)）。


## 1.7. tls_client_auth

[OAuth 2.0 Mutual TLS Client Authentication and Certificate-Bound Access Tokens](https://datatracker.ietf.org/doc/draft-ietf-oauth-mtls/?include_text=1)（以降 MTLS）という仕様があります。この仕様の「2. Mutual TLS for OAuth Client Authentication」には、クライアント証明書を用いるクライアント認証方式が定義されています。

MTLS で定義されているクライアント認証方式を用いるためには、まず、クライアントアプリケーションとトークンエンドポイントの間の接続が、Mutual TLS でなければなりません。
![client_auth_tls_client_auth_mutual_tls.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/a731fc86-0b5a-c65b-c811-321865cc933f.png)

通常の TLS では、サーバー側のみ証明書の提示をおこないますが、Mutual TLS では、クライアント側も自身の証明書を提示します。この結果、サーバー側にクライアント証明書が渡ってきます。
![client_auth_tls_client_auth_pass.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/1ce6880f-38e1-fdae-c831-4c0dd75c9ef0.png)

サーバーは、そのクライアント証明書をクライアント認証に用います。
![client_auth_tls_client_auth_client_auth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/df3af53e-fd77-2be3-7ca2-ae8fd287e6f6.png)

クライアント証明書として [PKI](https://ja.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%8D%B5%E5%9F%BA%E7%9B%A4) 証明書を用いる場合、クライアントは、その証明書の主体を識別するための情報を事前にサーバーに登録しておかなければなりません。主体を識別する情報は、次のいずれかです。

| 識別情報 | クライアントメタデータ名 |
|:--|:--|
| Subject Distinguished Name           | tls_client_auth_subject_dn |
| Subject Alternative Name, DNS        | tls_client_auth_san_dns    |
| Subject Alternative Name, URI        | tls_client_auth_san_uri    |
| Subject Alternative Name, IP address | tls_client_auth_san_ip     |
| Subject Alternative Name, Email      | tls_client_auth_san_email  |

サーバーは、受け取ったクライアント証明書の主体識別情報が事前登録されているものと一致することを確認し、もってクライアント認証とします。

このクライアント認証方式には `tls_client_auth` という名前が与えられています（[MTLS](https://datatracker.ietf.org/doc/draft-ietf-oauth-mtls/?include_text=1), 2.1.1. PKI Method Metadata Value）。

なお、クライアント証明書には OAuth 2.0 の文脈におけるクライアント ID は入っていないので、クライアント証明書だけではクライアントを特定することはできません。そのため、クライアント証明書を用いるクライアント認証をおこなう際は、別途クライアント ID をリクエストに含める必要があります。通常は `client_id` リクエストパラメーターが使用されます。


## 1.8. self_signed_tls_client_auth

クライアント証明書を用いるクライアント認証において、PKI 証明書ではなく、自己署名証明書を用いる場合もあります。自己署名証明書を用いる場合、クライアントは、証明書を事前にサーバーに登録しておかなければなりません。

このクライアント認証方式には `self_signed_tls_client_auth` という名前が与えられています（[MTLS](https://datatracker.ietf.org/doc/draft-ietf-oauth-mtls/?include_text=1), 2.2.1. Self-Signed Method Metadata Value）。


# 2. メタデータ

クライアント認証方式に関連するメタデータを紹介します。

## 2.1. サーバーメタデータ

### 2.1.1. token_endpoint_auth_methods_supported

トークンエンドポイントでサポートするクライアント認証方式です。`client_secret_basic` や `private_key_jwt` などの値を持つ配列です。


### 2.1.2. token_endpoint_auth_signing_alg_values_supported

トークンエンドポイントにおいてクライアントアサーションによるクライアント認証をおこなう際、クライアントアサーションの署名で使用可能なアルゴリズムです。`HS256` や `ES256` など、[RFC 7518](https://tools.ietf.org/html/rfc7518)（JSON Web Algorithms）の [3.1. "alg" (Algorithm) Header Parameter Values for JWS](https://tools.ietf.org/html/rfc7518#section-3.1) に列挙されている値を持つ配列です。
![jws_algs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/730de800-e3bc-ee3b-ef4c-019471fe3b73.png)


### 2.1.3. revocation_endpoint_auth_methods_supported

リボケーションエンドポイント（[RFC 7009](https://tools.ietf.org/html/rfc7009)）でサポートするクライアント認証方式です。内容は `token_endpoint_auth_methods_supported` と同じです。


### 2.1.4 revocation_endpoint_auth_signing_alg_values_supported

リボケーションエンドポイント（[RFC 7009](https://tools.ietf.org/html/rfc7009)）においてクライアントアサーションによるクライアント認証をおこなう際、クライアントアサーションの署名で使用可能なアルゴリズムです。内容は `token_endpoint_auth_signing_alg_values_supported` と同じです。


### 2.1.5. introspection_endpoint_auth_methods_supported

イントロスペクションエンドポイント（[RFC 7662](https://tools.ietf.org/html/rfc7662)）でサポートするクライアント認証方式です。内容は `token_endpoint_auth_methods_supported` と同じです。


### 2.1.6. introspection_endpoint_auth_signing_alg_values_supported

イントロスペクションエンドポイント（[RFC 7662](https://tools.ietf.org/html/rfc7662)）においてクライアントアサーションによるクライアント認証をおこなう際、クライアントアサーションの署名で使用可能なアルゴリズムです。内容は `token_endpoint_auth_signing_alg_values_supported` と同じです。


### 2.1.7. バックチャネル認証エンドポイント関連

[CIBA Core](https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html) で定義される**[バックチャネル認証エンドポイント](https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7)**は、仕様上、confidential クライアントしか利用できないことになっており、利用する際には必ずクライアント認証が必要となります。

|<img width="696" alt="ciba-ping-mode.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/b4fe5d95-70ce-92ff-9616-036e33bd0ea2.png">|
|:-:|
|参考：CIBA PING モードによるアクセストークン発行フロー|

認可サーバーのメタデータを列挙している [RFC 8141](https://tools.ietf.org/html/rfc8414) では、トークンエンドポイント、リボケーションエンドポイント、イントロスペクションエンドポイント毎にそれぞれ、サポートするクライアント認証方式（`*_endpoint_auth_methods_supported`）とサポートするクライアントアサーション署名アルゴリズム（`*_endpoint_auth_signing_alg_values_supported`）を表すメタデータが用意されています。そのため、CIBA Core 仕様策定中、バックチャネル認証エンドポイント用にもメタデータを新しく定義してはどうかと提案しました（【[Issue 102](https://bitbucket.org/openid/mobile/issues/102)】CIBA: Metadata for client auth at backchannel endpoint）。

しかしながら、最終的には、バックチャネル認証エンドポイント用に新しくメタデータを定義はせず、トークンエンドポイント用のメタデータで代用することとなりました。そもそも論として、エンドポイント毎にクライアント認証関連のメタデータを定義してきたこれまでの慣習が良くない、という話になりました。この議論については、「[世界最先端の認証認可技術、実装者による『CIBA』解説](https://qiita.com/TakahikoKawasaki/items/9b9616b999d4ce959ba3)」の「[3.2. クライアント認証](https://qiita.com/TakahikoKawasaki/items/9b9616b999d4ce959ba3#32-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E8%AA%8D%E8%A8%BC)」をご参照ください。


### 2.1.8. デバイス認可エンドポイント関連

[RFC 8628](https://tools.ietf.org/html/rfc8628)（OAuth 2.0 Device Authorization Grant）、いわゆるデバイスフローでは、新たに**デバイス認可エンドポイント**が定義されます。クライアントが confidential クライアントの場合、他のエンドポイントと同様、デバイス認可エンドポイントにアクセスする際にクライアント認証が要求されます。

|![device_flow+Authlete_ja.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/ba6073f7-6890-5fdb-020d-9ff5eac57dd9.png)|
|:-:|
|参考：デバイスフローと Authlete API|


ただし、仕様書には、デバイス認可エンドポイントがサポートするクライアント認証方式を表すメタデータについて言及がありません。そこで、「デバイス認可エンドポイントにおけるクライアント認証方式に関する記述を仕様書に追加する予定があるか」という問いを OAuth メーリングリストに投げてみました（[[OAUTH-WG] Client Authentication Method at Device Authorization Endpoint](https://mailarchive.ietf.org/arch/msg/oauth/TiFCEF8Ne1R83Em2DQ74gxbCOlE)）。

しかしながら、今までのところ、メタデータの扱いに関する議論に進捗はありません。デバイスフローについては公式テストも存在しないので、デバイス認可エンドポイントのクライアント認証方式の厳密な動作について気にする人もそれほどいないのでしょう。やむなく [Authlete](https://www.authlete.com/) の実装では、CIBA に倣い、トークンエンドポイントのメタデータで代用することにしています。


## 2.2. クライアントメタデータ

### 2.2.1. token_endpoint_auth_method

クライアントがトークンエンドポイントで使用するクライアント認証方式です。`client_secret_basic` や `private_key_jwt` などを指定します。クライアントタイプが public の場合はクライアント認証をおこなわないので、`none` を指定します。


### 2.2.2. token_endpoint_auth_signing_alg

クライアントがトークエンドポイントでクライアントアサーションを用いたクライアント認証をおこなう際、クライアントアサーションの署名に使うアルゴリズムです。[RFC 7518](https://tools.ietf.org/html/rfc7518)（JSON Web Algorithms）の [3.1. "alg" (Algorithm) Header Parameter Values for JWS](https://tools.ietf.org/html/rfc7518#section-3.1) に列挙されている値のいずれかを指定します。

クライアント認証方式に `client_secret_jwt` を選んでいる場合は、署名アルゴリズムは対称鍵系である `HS256`、`HS384`、`HS512` のいずれかになります。ただし、認可サーバーにより発行されたクライアントシークレットのエントロピーよりも高いビット数のアルゴリズムを選んでも、あまり益はないので注意してください。

一方、クライアント認証方式に `private_key_jwt` を選んでいる場合は、署名アルゴリズムに `ES256` などの非対称鍵系アルゴリズムを設定することになります。


# 3. Financial-grade API による要求事項

## 3.1. クライアント認証方式

従来の OAuth 2.0 や OpenID Connect よりも高いセキュリティーを要求する **[Financial-grade API](https://openid.net/wg/fapi/)**（**FAPI**）では、使用可能なクライアント認証方式に制限をかけています。

[RFC 6749](https://tools.ietf.org/html/rfc6749) に記述されている昔ながらのクライアント認証方式（`client_secret_basic` と `client_secret_post`）は、使用してはいけないことになっています。

Read-Only API 用のセキュリティープロファイルである [FAPI Part 1](https://openid.net/specs/openid-financial-api-part-1-ID2.html) では、使用可能はクライアント認証方式は次の 4 つです。

1. `client_secret_jwt`
2. `private_key_jwt`
3. `tls_client_auth`
4. `self_signed_tls_client_auth`

Read-and-Write API 用のセキュリティープロファイルである [FAPI Part 2](http://openid.net/specs/openid-financial-api-part-2-ID2.html) では、`client_secret_jwt` が使用不可となり、次の 3 つのクライアント認証方式のみが許されます。

1. `private_key_jwt`
2. `tls_client_auth`
3. `self_signed_tls_client_auth`

まとめると、次表のとおりです。
![client_auth_fapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/554cfcfb-fbf3-ec36-3bc4-ee1b7bb29bec.png)


## 3.2. クライアントアサーション署名アルゴリズム

[FAPI Part 2](http://openid.net/specs/openid-financial-api-part-2-ID2.html) の「[8.6. JWS algorithm considerations](https://openid.net/specs/openid-financial-api-part-2-ID2.html#jws-algorithm-considerations)」では、JWS の署名アルゴリズムに制限をかけています。Read-and-Write API の文脈では、`ES256` と `PS256` 以外のアルゴリズムを使用してはいけないことになっています。
![ps256_and_es256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/2a1497d5-34ba-9ee6-a0d3-b16b85754957.png)

この要求事項は、クライアントアサーションを用いるクライアント認証方式に影響を与えます。


## 3.3. キーサイズ

[FAPI Part 1](https://openid.net/specs/openid-financial-api-part-1-ID2.html) の「[5.2.2. Authorization Server](https://openid.net/specs/openid-financial-api-part-1-ID2.html#authorization-server)」の 5 番目の規定により、クライアント認証で RSA 系アルゴリズムが用いられる場合、鍵のサイズは 2048 ビット以上でなければなりません。また、6 番目の規定により、楕円曲線系のアルゴリズムが用いられる場合、鍵のサイズは 160 ビット以上でなければなりません。


# 4. Authlete

**[Authlete](https://www.authlete.com/)**（オースリート）は、

:white_check_mark: この記事で紹介したクライアント認証方式を全てサポートしています。

|![authlete_token_endpoint_auth_method.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/4aff33e7-d06b-7e29-7daa-9fcf7c2d621d.png)|
|:-:|


:white_check_mark: クライアントアサーション署名アルゴリズムも全てサポートしています。

|![authlete_token_endpoint_auth_signing_alg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/e2fbd893-a46f-f7b1-b817-cf60e760f08a.png)|
|:-:|

:white_check_mark: クライアント証明書系（MTLS）とクライアントアサーション系（Private Key）の双方のカテゴリーで公式 [FAPI 認証](https://openid.net/certification/#FAPI_OPs)を取得している、（サンドボックスではなく）商用環境で利用可能な、世界で唯一の実装です（2019 年 7 月 14 日現在）。

![certified_fapi_ops_20190714.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106044/6ea2979c-eb8d-8a10-d607-c73f1cc0facf.png)


# さいごに

いろいろなサービスが API として提供されるようになり、便利な世の中になってきました。しかし、その一方で、不適切な実装のせいで、セキュリティー問題も頻発するようになってしまいました。

API 公開にあたってセキュリティーを重視されたい場合は、Financial-grade API の実装として公式認証を取得している **Authlete** の利用をご検討ください。お問い合わせは、Authlete 社の[お問合せページ](https://www.authlete.com/ja/contact/)、または sales@authlete.com までご連絡ください。よろしくお願い致します。