クライアント証明書を要求するAPIの作成から公開まで

## はじめに
APIにアクセスしてくるクライアントを認証するためにクライアント証明書を使いたいケースもあります。IBM API ConnectではAPI定義にクライアント認証を選択し、使用する証明書を登録しておくと、簡単にクライアント証明書を使った認証を要求するAPIを作成することが可能です。ここでは特定のヘッダーを使ってクライアント認証するケースを紹介します。

## 前提条件
* 環境
 1. IBM API Connect (IBM Cloud版で、執筆時点V5.0.8.xと思われます)のLite（無料）版。
 2. 当たり前ですがIBM Cloudのアカウントはあるものとします。
 2. カタログ設定、開発者ポータル設定はできているものとします。

## 手順
手順は以下の流れです。

１. クライアント証明書を作成
   １. まずは鍵を作成
  
  ```
  openssl genrsa -out CLIENT_CERT.key 2048
  ```

   ２. この鍵を元にCSRを作成
  
  
  ```
  openssl genrsa -out CLIENT_CERT.key 2048
  ```

  
   ３. このCSRに署名してクライアント証明書を発行
  
  ```
  openssl x509 -sha256 -req -days 3650 -in CLIENT_CERT.csr -signkey CLIENT_CERT.key -out CLIENT_CERT-ca.crt
  ```

２. IBM Cloudにログインし、API ConnectのAPI ManagerのAPI定義画面（ドラフト）に遷移
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/16c24383-5d9e-15af-f595-d79faeeccc08.png)

３. APIを新規作成し、以下を設定
　１. 基本パスの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/a64bc534-14f6-d098-fb34-0aedce55d519.png)

　２. アプリケーションの認証を有効化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/598c180e-5c4c-c588-ca1e-5d47fb6b64ab.png)

　３. セキュリティ定義のクライアントIDの設定はそのまま
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/5faf3359-ab0d-8e03-669e-a8bd00958046.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/939e47da-0e2e-1470-98a2-6e449f7787dc.png)

　４. パスを設定、メソッドはデフォルトのGETのままで、パラメータにX-Client-Certificateヘッダーを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/4c0bdf24-eb3b-6a69-97e5-13f89c602646.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/ef183d73-38e6-85ba-24a2-eda95d7fafd0.png)

　５. アセンブルを開く
　　１. 今回はバックエンドを呼ばず固定レスポンスを折り返すモックAPIとするので、invokeを消す
　　２. 変数設定ポリシーをドラッグ＆ドロップする
　　３. message.status.codeに200、message.bodyに{"Status": "Authenticated"}を設定し、固定レスポンスを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/f220787a-03c9-83d9-85d1-1e5c8b33d448.png)

　６. APIを保存したら、製品（新規でもデフォルトでも良いですが、ここでは既存の製品を使用）に追加してカタログにステージング＆公開
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/64b9e937-11a9-0b88-c95f-e24cb99af9eb.png)

ここではTestProductを選択して追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/e479723e-ae03-a0ac-931c-f6bcca5431b5.png)

TestProduct製品をTestカタログにステージング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/8ec10efc-47bc-bbb4-9395-7f0d3a2fdc98.png)

Testカタログにステージングされた製品を公開
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/3389130b-b725-b915-b5ec-176dfd84f8cd.png)

公開ステータスに変わる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/2406aa6a-91a0-9a20-b39b-1a0c0867af46.png)


４. 開発者ポータルにログインし、公開した製品があることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/75387d7c-fe05-d570-9a8d-873fdff5fa2d.png)

５. アプリケーションを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/4a560ff6-e018-2777-bec3-33ab38cfac92.png)

　１. アプリの名前（タイトル）を入れる
　２. 証明書のセクションに1で作成した証明書の中身をコピペしてSubmit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/c7a37b12-261b-5163-698b-e7dc8009c75f.png)

　３. クライアントIDとシークレットが表示されるのでメモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/8052990e-5637-61d6-8f23-af0d44a8dee6.png)

　４. 3.6で公開された製品をサブスクライブする

available APIsをクリックすると製品一覧に飛ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/438066be-7320-f4bb-dd78-4cf9f965c986.png)

先ほどのTestProductを選択してSubscribeをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/efe276fe-f0df-be29-3bd3-0b7cb86c5892.png)

サブスクライブしたいアプリとして先ほど作成したアプリを選択してSubscribe
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/17065fb4-3321-bb1e-3466-0e565aaf7c87.png)

サブスクライブ成功メッセージが出るのを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/28414a1a-0296-3fe4-689e-5063cd516205.png)

作成したアプリのページに戻るとサブスクリプション一覧に先ほどのTestProductがあることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/c6b45961-f9bc-38a3-6c07-c6f7d6cc13c8.png)


６. APIにアクセスしてみる。先ほど設定したX-Client-Certificateヘッダの値に、作成した証明書の中身をコピペで入れてリクエストする。ここではPostmanを使用。
　　　１. エンドポイントに設定したパス、メソッドを選択、
　　　２. X-IBM-Client-Idヘッダーに5.3でメモしたクライアントIDをセット
　　　３. 3.4で設定したX-Client-Certificateヘッダに1で作成した証明書の中身（PEM形式）をコピペ
　　　４. 呼び出しをクリックしてリクエスト実行
　　　５. 200 OKの{"Status": "Authenticated"}が返ることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/8201e33e-6df9-b59c-cd4d-15292d6c70f9.png)
　　　６. 証明書の値を書き換えてリクエストすると、401 Unauthorizedエラーになることを確認（証明書が無効と怒られる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/8a781538-e0d6-8d22-15aa-1afa1b44b538.png)

　　　７. 証明書のヘッダーの中身を空にしてリクエストすると、401 Unauthorizedエラーになることを確認（MTLSを使用してないと怒られる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129662/7051e846-f130-cd6e-51e5-5abd21567632.png)



## まとめ
クラウド版のAPI Connectにて、クライアント認証を要求するAPIが簡単に公開できることがわかりました。オンプレ版のAPI Connectの場合だとGateway側のMTLS設定も可能のため、MTLS通信におけるクライアント証明書によるクライアント認証も可能です。

## 参考
* https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.cmc.doc/ssl.html
* https://www.ibm.com/support/knowledgecenter/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/task_apionprem_creating_apis.html#task_tq2_11r_xt__tls_mutual_auth
* https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.devportal.doc/task_cmsportal_registerapps.html#task_devportal_registerapps__x509_cert
* https://developer.ibm.com/apiconnect/2018/09/14/tls-profiles-ibm-api-connect/
* https://developer.ibm.com/answers/questions/464390/tls-mutual-auth-at-an-api-level/