4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[OCI] Entra IDで認証して、API GatewayにデプロイしたAPIを実行する

Posted at

はじめに

この記事は、Oracle Cloud Infrastructure Advent Calendar 2025 の Day 16 の記事です。
OCI でもこんな事が出来るんだよって事をもっと知ってほしくて書いてみました。
頑張っていきましょう。よろしくお願いします。

目的

こちらの記事は、OCI (Oracle Cloud Infrastructure) に関する Howto 系の記事です。
この記事を読むことで、下記の操作が出来るようになることを目的としています。

  • OCI Functions のリソースをデプロイすることが出来る
  • OCI API Gateway をデプロイして、クライアントから API 呼び出しが出来る
    • API Gateway の背後には、予め作成しておいた Functions を配置します
  • 最終的には Entra IDを使って、API を呼び出すために認証が必要な状態にする
    • 認証方法は、Entra ID から発行されたトークンを API Gateway 側で検証する「リモート JWKS」を用いた方法です

手順

OCI Functions の作成

アプリケーションの作成

OCI コンソールからアプリケーションを作成します。
今回の場合、東京リージョンにアプリケーションを作成します。

image.png

名前は適当に、VCN やシェイプに関しても適宜選択します。
API Gateway 配下にデプロイする予定なので、アプリケーションは Private サブネットに展開します。

image.png

Public サブネットに展開するなら問題ありませんが、もし Private サブネットに展開する場合はサービス ゲートウェイへのルーティングを構築してください。
理由は、アプリケーションがコンテナ レジストリからイメージを PULL するためのルーティング設定が必要なためです。

下図のように、当該 VCN に対してサービス ゲートウェイを作成して、ルーティング設定を構築します。

まずはサービス ゲートウェイを作成。
image.png
image.png

その後、Private サブネット用のルート表を作成し、Private サブネットに紐づけます。
image.png

サブネットに対するルート表の紐づけは、サブネットの [アクション - 編集] から指定が可能です。

image.png

image.png

ファンクションの作成

下記の公開情報を参考に、ファンクションを作成します。

ファンクションですが、適当に作成します。
作成方法が分からない方は、アプリケーションの詳細画面にある「スタート・ガイド」を参考にすると良いです。
例えば「クラウド・シェル設定」のガイドの表示をクリックすると、ファンクションの作成からデプロイまでのコマンドが記載されています。
image.png

私はローカル環境で開発して OCI にデプロイするスタイルが好きなので、せっかくなので WSL2 の Ubuntu 環境からファンクションの作成とデプロイを実施しようと思います。

OCI コンソールからコンテナ レジストリを作成

ファンクションですが、関数として動作させる処理をコンテナ イメージ化する必要があります。
わざわざコンテナ レジストリを作成しなくても良いですが、(検証環境の制限上) 自分が管理しているコンパートメントにコンテナ レジストリを作成します。

コンテナ レジストリ自体の作成はとても簡単です。
下記公開情報をもとに作成しましょう。

作成したコンテナ レジストリへイメージを PUSH するには、認証トークンの作成が必要です。
こちらも上記公開情報を元に作成し、生成されたトークンをコピーして控えておきましょう。

image.png

WSL2 の Ubuntu 環境にて、ファンクション作成のための準備を行う

もし同じように WSL2 環境にてファンクションを作成されたい場合は、事前に下記の公開情報を元に WSL2 のセットアップをお願いします。

ローカル環境でファンクションを作成するには、事前に下記の準備が必要です。

  • docker のインストール
  • OCI プロファイルの設定 (OCI CLI のインストールでも OK)
  • Fn CLI のインストール

docker のインストール方法については省略します。

OCI プロファイルの設定については、下記公開情報の "2.API署名キーおよびOCIプロファイルの設定" をご参考ください。

image.png

"~/.oci/config" に書き込む内容は、あとからユーザー情報の "APIキー" から確認可能です。
対象のフィンガープリントから "構成ファイルの表示" をクリックして、確認してみてください。
image.png

公開情報では、OCI 側で作成した秘密鍵をダウンロードするように明記されておりますが、自分で作成した秘密鍵を使うことも可能です。
その場合は、APIキー作成時に公開鍵の内容を貼り付ける必要があります。

ここで注意が必要な事として、パス フレーズがある鍵ペアを作成すると Fn CLI が動作しない可能性があります。

Fn CLI を使ったデプロイ時に、"Fn: can not create client, bad configuration: did not find a proper configuration for private key" のエラーが発生する。

そのため自分で秘密鍵を作成する場合は、下記コマンドのようにパス フレーズ無しで作成してください。

openssl genrsa -out oci_api_key_nopass.pem 2048
openssl rsa -pubout -in oci_api_key_nopass.pem -out oci_api_key_nopass_public.pem

Fn CLI のインストール方法についても、OCI プロファイルの設定が記載してある公開情報に記載されております。
"3.Fn ProjectのCLIのインストール" の箇所をご参考にインストールします。

image.png

このように、各種パッケージのバージョンが確認できていれば OK です。

image.png

ファンクションを作成する

ファンクションの作成前に、Fn CLI のセットアップが必要です。

fn create context <コンテキスト名> --provider oracle
fn use context <コンテキスト名>
fn update context oracle.profile <~/.oci/config ファイルで指定したプロファイル名>
fn update context oracle.compartment-id <Functions のアプリケーションを管理しているコンパートメントの OCID>
fn update context api-url https://functions.<region-identifier>.oraclecloud.com

# 例
# fn create context my-func-context --provider oracle
# fn use context my-func-context
# fn update context oracle.profile MYPROFILE
# fn update context oracle.compartment-id ocid1.compartment.oc1..aaa****6ka
# fn update context api-url https://functions.ap-tokyo-1.oraclecloud.com

次にファンクションの雛形を作成します。
ここでは Python のファンクションを作成します。

fn init --runtime python python-func
cd python-func

image.png

次に、予め作っておいたコンテナ レジストリと紐づけてログインします。

fn update context registry "ocir.<region-identifier>.oci.oraclecloud.com/<tenancy-namespace>"
docker login ocir.<region-identifier>.oci.oraclecloud.com -u '<tenancy-namespace>/<user-name>'
# テナントが Oracle Identity Cloud Service とフェデレートされている場合は、ユーザー名部分が異なるので注意です。
# docker login ocir.<region-identifier>.oci.oraclecloud.com -u '<tenancy-namespace>/oracleidentitycloudservice/<user-name>'
# Password は、予め作成しておいた認証トークンを指定してください。

# 例
# fn update context registry "ocir.ap-osaka-1.oci.oraclecloud.com/*****"
# docker login ocir.ap-tokyo-1.oci.oraclecloud.com -u "*****/oracleidentitycloudservice/jun.kitayama@*******" 

その後、fn -v deploy --app <アプリケーション名>を実行してファンクションをアプリケーションにデプロイします。

もし下記のようなエラーが発生する場合は、予め作成しておいたコンテナ レジストリに対してデプロイ予定のファンクションと同名 (今回の場合だとpython-func) のレジストリを作成してから改めて fn deploy コマンドを実行してみてください。

denied: User UserId(ocid1.user.oc1..***********) not authorized

デプロイに成功すると、Successfully created function: python-func with ocir.ap-tokyo-1.oci.oraclecloud.com/....のメッセージが表示されます。

OCIコンソールからアプリケーションを確認すると、下図のとおりファンクションがデプロイされていることが確認出来ます。

image.png

下記のコマンドを実行して、デプロイしたファンクションが実際に動作することを確認します。

fn invoke <アプリケーション名> <ファンクション名>

# 例
# fn invoke jk-function-app-01 python-func

image.png

もし「Error invoking function. status: 502 message: Failed to pull function image」のようなエラーが発生する場合は、アプリケーションが Private サブネットに展開されておりコンテナ レジストリにアクセス出来ていないかもしれません。
その場合は、アプリケーションの作成で説明したとおり、サービス ゲートウェイの設定を見直してください。

問題なく{"message": "Hello World"}が返ってこれば、ファンクションのデプロイは完了です。

OCI API Gateway の作成

クライアントが直接アクセスする OCI API Gateway を作成します。

API Gateway がファンクションを呼び出せるようにポリシーを作成する

OCI Functions は匿名実行が出来ません。
実行しようとすると、IAM 検証で 401 を返されます。
そのため、API Gateway からファンクションを呼び出せるようにポリシーの作成が必要です。

下記の公開情報を参考に、動的グループの作成 & 作成した動的グループへのポリシー割り当てを行います。
「FunctionsへのAPIゲートウェイ・アクセスのポリシーの設定」の箇所を参考にしましょう。

API Gateway リソースの作成

OCI コンソールから、API Gateway を作成します。
API Gateway は、「開発者サービス - API 管理」のカテゴリにあります。
「ゲートウェイの作成」をクリックして、API Gateway リソースを作成しましょう。
image.png

下図のように、パブリックな API Gateway を作成します。
デプロイ先のサブネットも、Public なサブネットを指定しましょう。

image.png

デプロイメントの作成

API Gateway リソース作成後に、デプロイメントを作成します。
image.png

基本情報は、名前とパス接頭辞を指定。
image.png

「認証なし」を一旦選択します。
image.png

予め作成しておいたファンクションへルーティングするための設定を行います。
下図のような設定の場合は、"GET /python-func" を呼び出すと予め作成しておいたファンクションの API が呼び出されます。

image.png

もし別のファンクションを呼び出す API を定義したい場合は、右下の「別のルート」をクリックすることでルーティング設定を追加出来ます。
image.png

その後、作成をクリックしてしばらくするとデプロイメントが作成されます。
デプロイメント作成後、エンドポイントをコピーすることで API を呼び出すことが出来ます。
image.png

下記の URL にアクセスすることで、API Gateway を経由してファンクションの呼び出しが可能です。

<コピーしたエンドポイント>/<デプロイメント作成時に指定したパス>

問題がなければ、下図のとおり JSON のレスポンスが返却されます。

image.png

もし API の呼び出しに失敗する場合は、API Gateway をデプロイした VCN に対する 443 ポートへの通信が許可されていないかもしれません。
当該 VNC のサブネットに紐づいたセキュリティ リストを確認し、外部から 443 ポートへの通信が許可されていることを確認しましょう。

image.png

ソース (0.0.0.0/0) から 443 番ポートへの通信を許可します。
image.png

Entra ID を使った認証

せっかくなので、API Gateway の認証機能を用いてセキュアに API を呼び出せるようにしてみます。
今回は Entra ID を使って、リモート JWKS を使った検証を API Gateway 側で実施しようと思います。

Entra ID 側の構成は下記のようなイメージです。

Entra ID
 ├── API アプリ(リソースアプリ) ← 1つだけ
 │      Application ID URI = api://my-oci-api
 │      Scope = api://my-oci-api/access_as_user
 │
 ├── クライアントアプリA(サービスプリンシパルA)
 ├── クライアントアプリB(サービスプリンシパルB)
 └── クライアントアプリC(サービスプリンシパルC)
           ↓(それぞれが以下のスコープでトークン取得)
           scope=api://my-oci-api/access_as_user
           ↓
OCI API Gateway(JWT検証)

Entra ID 側でアプリケーションを作成する

下記から、Microsoft Entra 管理センターにアクセスします。

アプリの登録から、「新規登録」をクリック。

image.png

適当な名前を指定して、「登録」をクリックします。

image.png

API の公開から「Scope の追加」をクリック。
「保存してから続ける」をクリックします。
image.png

下図のように、スコープ名や管理者の表示名などを指定します。
アプリケーション ID の URI は後で使用するのでコピーしておきましょう。
「スコープの追加」をクリックします。
image.png

アプリ ロールから「アプリ ロールの作成」をクリック。
下図のようにパラメーターを指定して、「適用」ボタンをクリックします。
image.png

次に、同じ方法でクライアント アプリケーションを新たに作成します。
image.png

作成したクライアント アプリケーションに対して、API のアクセス許可のページから「アクセス許可の追加」をクリック。
下図のように、先程作成した API を追加します。
image.png

image.png

「既定のディレクトリに管理者の同意を与えます」をクリックし、「はい」をクリックします。
image.png

API Gateway の API を呼び出すためにトークンを指定する必要があるので、トークン取得のためにクライアント アプリケーションに対してクライアント シークレットを追加します。
作成後は、必ずクライアント シークレットの値を控えておきましょう。
image.png

これで、Entra ID 側の設定は完了です。

API Gateway のデプロイメントを更新

OCI コンソールを開いて、先程作成した API Gateway のデプロイメントを編集します。
image.png
image.png

認証ステップにて、認証なしから単一認証を選択します。
下図のように認証タイプやトークンの場所などを指定します。
JWT トークン・ヘッダー名には "Authorization" を、認証スキームには "Bearer" を指定します。
image.png

検証タイプは、タイプを「リモートJWKS」を選択します。
JWKS URIには、下記を指定します。

https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys

image.png

追加のJWT検証の発行者とオーディエンスに指定する値は下記のとおりです。

https://sts.windows.net/<tenant-id>/
api://<oci-appの client_id>

image.png

そして次へ次へとクリックしていき、変更した内容を保存します。

トークンを取得して API を呼び出す

適当な HTTP 実行ツールを使ってトークンを取得します。
自分は Postman を使って取得しました。

トークンを取得するための URL やリクエスト情報は下記を参考ください。
取得した access_token の値は、コピーして控えておきます。

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token

client_id: <client-app-A の client_id>
client_secret: <client-app-A の secret>
scope: api://<oci-appの client_id>/.default
grant_type: client_credentials

image.png

その後、API Gateway にデプロイした API を呼び出します。
呼び出す際には、リクエスト ヘッダーに Authorization: Bearer <access_token の値> を指定しましょう。
すると、下図のとおり期待どおりレスポンスが返ってくることを確認できます。

image.png

試しにトークンを意図的に指定しなかった場合は、下図のとおり 401 エラーが返却されました。
これも期待どおりですね。

image.png

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?