【OCI】IAM Identity Domainを使ってAPI Gatewayに認証を実装してみる

# はじめに

今回はOracle Cloud Infrastructure（OCI）のIAM Identity Domainの機能を使って
API GatewayにOAuth2.0を基盤としたJWT認証をかけたいと思います。

前回、以下の記事でAuth0を利用した認証方法をご紹介しましたが、  
今回はOCIのネイティブ機能だけ使った方法を解説します。

【OCI】API Gatewayに認証を実装してみる
https://qiita.com/atwits/items/0774e725c185b3dee890

あとは公式サイトのこのあたりを参考にして頂ければと思います。
https://docs.oracle.com/ja-jp/iaas/Content/Identity/applications/to-configure-oauth.htm

流れに関してはAuth0の時とそれほど変わらないです。

■API GatewayでJWT認証を使うまでの簡単な流れ
①IAM Identity Domainで統合アプリケーションを作成
②API Gatewayでトークンを検証する設定を入れる
③IAM Identity DomainのAPIでトークン発行
④API Gatewayを④のトークンを使ってコールする

今回の構成は下記の通りです。

■構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/2f0d9f45-294b-9116-ee4b-9158327d03d9.png)

API Gateway（Functions）の基本機能については前回同様に
過去のQiitaに簡単にまとめてあります。

■【OCI】API Gateway経由でFunctionsのAPIを呼び出してみる
https://qiita.com/atwits/items/f9dcc82f6a552c3df390

◆目次
1.IAM Identity Domainの設定
2.API Gatewayの設定
3.APIの動作検証

## 1. IAM Identity Domainの設定

それでは早速、IAM Identity Domainの設定に入りたいと思います。

OCIにログインしたら、左上メニュー[Ξ]から
[アイデンティティとセキュリティ] - [ドメイン]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/94da7ee9-9a6b-325e-1d59-1c629ea87bba.png)

次に設定したいドメインを選択します。
（デフォルトのOracleIdentityCloudServiceを選択しても構いません）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/ab805565-702a-541f-8d48-6fc3ac633651.png)

ここでは後でAPIのエンドポイントとして使うため、
ドメインURLをコピー（保存）しておき、統合アプリケーションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/e6ba1e9b-e976-f563-34d9-699a5cb01c53.png)

続いてアプリケーションの追加を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/9ec7f463-1668-deae-b086-1b37bb29e3c2.png)

機密アプリケーションを選択して、ワークフローの起動を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/41258187-f4b4-678e-3bca-82d03aeee2a1.png)

任意の名前（ここではapp_jwt）をつけて次を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/f731d059-bafc-3100-3d3e-7fcc4c98ee70.png)

「このアプリケーションをリソース・サーバーとして今すぐ構成します」の
ラジオボタンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/09852475-8ce5-c50a-4b25-2e461065e6b6.png)

今回は特に使用しませんのでプライマリ・オーディエンスに任意の値を入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/b563ded1-a37f-5925-773a-323941a8c63d.png)

そのまま「このアプリケーションをクライアントとして今すぐ構成します」の
ラジオボタンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/0b264959-38e8-99ab-619e-9c6084994906.png)

クライアント資格証明とJWTアサーションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/3ee24adc-bcff-1914-d238-44cc46a49503.png)

ここでは下記を選択して次に進みます。
クライアント・タイプ: 機密
IDトークン暗号化アルゴリズム: A256CBC-HS512
クライアントIPアドレス: 任意の場所
認可されたリソース: すべて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/76439653-f72a-ee47-eed8-84a73c4552f2.png)

最後に「スキップして後で実行」を選択したまま、終了を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/d14d670f-b2e0-5880-aac9-4c730514fd07.png)

統合アプリケーションの作成が完了したらアクティブ化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/e59a1b83-2e96-00d1-81ba-39c359eeeb86.png)

下の方にスクロースするとクライアントID、クライアント・シークレットがあるので
コピーしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/cd9a1d0d-ac21-6e5c-e7c9-761a43488777.png)

以上でIAM Identity Domainの設定は終了です。

## 2. API Gatewayの設定

ここでは既にAPI Gateway + Functionsが設定されている前提で
JWT認証を設定する部分を説明したいと思います。

左上メニュー[Ξ]から開発者サービスを選択し、
ゲートウェイを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/6823a1fc-378e-1d49-d69f-e8c8813988da.png)

あとは認証設定したいAPI Gatewayを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/f81a3090-9f59-24a2-62af-3c1f14d77e1d.png)

続いてデプロイメントを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/c937a1ef-3e0f-7b68-559d-374971c98e76.png)

ここで編集を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/0bc2a12d-067f-76ac-3f7d-fdeb3c52f158.png)

下記の通り、赤枠部分の通りとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/1b44b8a8-80c9-732d-e23f-232827a4f4b8.png)

ここでは下記の選択／入力をしています。
選択: 単一認証
匿名アクセスの有効化: チェック
認証タイプ: OAuth 2.0 / OpenID Connect
トークンの場所: ヘッダー
JWTトークン・ヘッダー名: Authorization
認証スキーム: Bearer

下にスクロールして下記の赤枠も選択／入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/0ac16378-7625-98a2-ea70-52bfa867a5e7.png)

こちらは下記の選択／入力をしています。
タイプ: リモートJWKS
JWKS URI: [ドメインURL]/admin/v1/SigningCert/jwk
例. https://idcs-263db******.identity.oraclecloud.com/admin/v1/SigningCert/jwk

さらにスクロールして下記の赤枠も選択／入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/92d04d5a-3ab3-a8cc-a433-4ad2fe0efe19.png)

こちらは下記選択／入力をしています。
許可されている発行者: https://identity.oraclecloud.com/ (固定値)
許可されているオーディエンス: [ドメインURL]
例. https://idcs-263db******.identity.oraclecloud.com
※こちらは前述で設定したオーディエンスではなく、ドメインURLを設定します。

以上で変更の保存を選択したらAPI Gatewayの設定は終了です。

## 3. APIの動作検証

それでは最後にAPIの動作検証をしてみます。

最初にIAM Identity Domainでアクセストークン（JWT）を発行します。

■設定情報
```
[Method] POST
[Endpoint] <ドメインURL>/oauth2/v1/token
[Header] 
 Content-Type: application/x-www-form-urlencoded
 Authorization: Basic <Base64認証値>
[Body]
 grant_type=client_credentials&scope=urn:opc:idm:__myscopes__
```
ドメインURL 例. https://idcs-263db******.identity.oraclecloud.com

■Base64認証値の生成方法

例.
クライアントID: ABCDE
クライアント・シークレット: 12345

クライアント・シークレットを「:」でつなげた文字列を作成
 →　ABCDE:12345

それをBase64エンコードしたもの
→ QUJDREU6MTIzNDU=

最終的なヘッダーは以下のようなイメージとなります。
Authorization: Basic QUJDREU6MTIzNDU=

上記設定した上でPOSTを実行すると下記のようなレスポンスが返ってきますので
このaccess_tokenをコピーしておきます。
```
{
    "access_token": "eyJ4NXQcN5zdEKfw*****",
    "token_type": "Bearer",
    "expires_in": 3600
}
```

あとはAPI Gatewayのヘッダーにトークンを埋め込むだけで完了です。

■設定情報

```
[Method] POST (任意)
[Endpoint] *API Gatewayのエンドポイント
[Header] 
 Content-Type: application/json
 authorization: Bearer <トークン>
[Body] *API GatewayのPOSTデータ
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493138/3a02268a-0794-7ac2-2482-1002cc3d42a6.png)

上記でPOSTすればAPIがコールされます。
※デフォルト設定では3600秒(1時間)経過するとトークンの有効期限が切れて認証エラーとなります。

## おわり
以上、IAM Identity DomainのJWT認証を使って簡単にAPI Gatewayに認証を実装することができました。