Azure API ManagementとActive Directoryを連携してOAuth2認証する方法
2021/04/26
Table of Contents
記事を書いた理由
基本的には以下ドキュメントを参考に進めていけば、API ManagementにOAuth2認証を追加できます。
しかし、ドキュメントに記載されている手順が多く、またある程度Azureを知っている前提で記載されていることから、私にとっては難易度が非常に高かったです。
今後、同じような手順を踏む方々、Azure初心者の方々でも完走できるよう、より詳細な手順を記載します。
手順の概要
以下のような手順でOAuth2認証に対応したAPIを作成します。
- Azure Learnを参考にAPIを作成する
- Azureのドキュメントを参考に認証を追加する
- APIを表すApp(backend-app)を作成
- クライアントを表すApp(client-app)を作成
- Azure ADでclient-appがbackend-appを呼び出せるようアクセス許可
- APIにOAuth2認証を追加
- APIにアクセス制限ポリシーを設定
- Developer portalを使ってテスト
手順を進めるごとに様々なリソースを作成するので、リソース同士がどのように関連しているのかわからなくなります。最終的には以下のようなリソース構成を目指していることを頭においた上で、読み進めてください。
なお、画面の表記に関する記載は混乱を避けるため「英語」で統一します。ご了承ください。
Azure Learnを参考にAPIを作成する
まずはOAuth2認証がない通常の(サブスクリプションキー認証の)APIを作成します。この手順については、次のチュートリアルがわかりやすくまとめられているのでこの手順通りに進めてください。
注意すべきポイントを列挙します。
アカウントによってはSandbox環境が使えないことがあるようです。
一方、ローカルPCからだとデプロイに失敗することがあります。
Azure PortalからCloud Shellを開き、ここで実行すると確実です。
既にResource Groupが存在するアカウントを利用すると、思わぬResource Groupにデプロイされる
このチュートリアルで利用するsetup.shは、既に存在するResource Groupのうち最初のResource Groupにデプロイしようとします。以下のように修正することで、指定したResource Groupにデプロイすることができます。
diff --git a/setup.sh b/setup.sh
index e3e203a..81c2fb2 100644
--- a/setup.sh
+++ b/setup.sh
@@ -6,8 +6,8 @@ export PRODUCT_FUNCTION_NAME=ProductFunction$(openssl rand -hex 5)
export ORDER_FUNCTION_NAME=OrderFunction$(openssl rand -hex 5)
# Get the resource group and location
-export RESOURCE_GROUP=$(az group list --query "[0].name" -o tsv)
-export LOCATION=$(az group show --name $RESOURCE_GROUP | jq -r ".location")
+export RESOURCE_GROUP=apimanagement
+export LOCATION=japaneast
printf "\nThe resource group is called $RESOURCE_GROUP and is located in $LOCATION\n"
API Managementの初回デプロイに時間がかかる
チュートリアルには「30分程度かかる可能性がある」と記載されていますが、私の環境だと45分ほどかかりました。気長に待ちましょう。
APIを表すApp(backend-app)を作成
本家のドキュメントのこの部分に相当する手順です。
Azure PortalにてActive Directory→App registrations→New registrationの順でクリックします。
以下の通り入力して「Register」をクリックしてください。
- Name: backend-app
- Supported account types: Accounts in this organizational directory only (xxx only - Single tenant)
- Redirect URI: Webを選択、URIは空
Azure PortalにてActive Directory→App registrations→backend-appの順でクリックします。
Application (client) ID
の値をメモしておきましょう。
そのまま、Expose an API→Setをクリックします。
デフォルトの値のまま、Saveをクリックします。
+Add a scope をクリックします。
以下の通り入力して「Add scope」をクリックしてください。
- Scope name: products
- Who can coonsent?: Admins only
- Admin consent display name: products
- Admin consent description: products
- State: Enabled
Scopeが作成できたら、ScopeのURLをメモしておきましょう。
クライアントを表すApp(client-app)を作成
本家のドキュメントのこの部分に相当する手順です。
Azure PortalにてActive Directory→App registrations→New registrationの順でクリックします。
以下の通り入力して「Register」をクリックしてください。
- Name: client-app
- Supported account types: Accounts in this organizational directory only (xxx only - Single tenant)
- Redirect URI: Webを選択、URIは空
Azure PortalにてActive Directory→App registrations→client-appの順でクリックします。
Application (client) ID
の値をメモしておきましょう。
そのままCertificates & secrets→+New client secret→Addをクリックします。
出来上がったClient secretの Value
をメモしておきましょう。
Azure ADでclient-appがbackend-appを呼び出せるようアクセス許可
本家のドキュメントのこの部分に相当する手順です。
Azure PortalにてActive Directory→App registrations→client-app→API permissions→+Add a permissionの順でクリックします。
My APIs→backend-appの順でクリックします。
Permissionsにてproductsを選択し、Add permissionsをクリックします。
Grant admin consent for xxxをクリックします。ここは全体管理者と特権ロール管理者、および一部のアプリケーションでは、アプリケーション管理者とクラウド アプリケーション管理者のいずれかが付与されたADユーザーでないとクリックできないので注意が必要です。
APIにOAuth2認証を追加
本家のドキュメントのこの部分に相当する手順です。
OAuth2認証に使用するエンドポイントを確認する
Azure PortalにてActive Directory→App registrations→Endpointsをクリックします。
Authorization EndpointおよびToken Endpointをそれぞれメモします。
API ManagementにOAuth2認証を設定する
Azure PortalにてAPI Management services→(Azure Learnの手順に沿って作成したインスタンス)→OAuth 2.0 + OpenID Connect→OAuth 2.0→+Addをクリックします。
以下の通り入力してください。この時、「Create」はまだクリックしないようにしましょう。
- Display name: oauth2
- Client registration page URL: http://localhost
- Authorization grant types: Authorization code
- Authorization endpoint URL: (先の手順でメモしたAuthorization Endpoint)
- Authorization request method: GET, POST
- Token endpoint URL: (先の手順でメモしたToken Endpoint)
- Default scope: (先の手順でメモしたScopeのURL)
- Client ID: (先の手順でメモしたclient-appのClient ID)
- Client Secret: (先の手順でメモしたclient-appのClient Secret)
入力が完了したら、Redirect URIをメモして、Createをクリックします。
client-appにリダイレクトURIを紐付ける
Azure PortalにてActive Directory→App registrations→client-app→Authentication→Platform configurations→+Add a platformの順にクリックします。
Webを選択します。
先の手順でメモしたRedirect URIを入力し、Configureをクリックします。
APIでOAuth2認証を使用するよう設定する
Azure PortalにてAPI Management services→(Azure Learnの手順に沿って作成したインスタンス)→APIs→(Azure Learnの手順に沿って作成したProductsのAPI)→Settingsの順にクリックします。
SecurityのUser authorizationを「OAuth 2.0」とし、OAuth 2.0 serverを「oauth2」とします。
APIにタグを付与する
前の手順に引き続きSettingsタブにて以下のようなタグを付与します。
- Products:
Starter
およびUnlimited
- Gateways:
Managed
APIにアクセス制限ポリシーを設定
本家のドキュメントのこの部分に相当する手順です。
Azure PortalにてAPI Management services→(Azure Learnの手順に沿って作成したインスタンス)→APIs→(Azure Learnの手順に沿って作成したProductsのAPI)→Design→ProductDetails→</>の順にクリックします。
アクセス制限ポリシーを以下の通り修正します。
<policies>
<inbound>
<base />
<set-backend-service id="apim-generated-policy" backend-id="productfunction20ca1248af" />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
<openid-config url="https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration" />
<required-claims>
<claim name="aud">
<value>(backend-appのアプリケーションID)</value>
</claim>
</required-claims>
</validate-jwt>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Developer portalを使ってテスト
本家のドキュメントのこの部分に相当する手順です。
Developer portalを有効化する
Azure PortalにてAPI Management services→(Azure Learnの手順に沿って作成したインスタンス)→Portal overviewをクリックします。
次の順にクリックします。
- Enable Azure AD
- Enable CORS
- Publish
Developer portalをクリックし、開いた画面のURLをメモします。
ブラウザのシークレットウインドウを開いて、メモしたURLにアクセスします。
APIのサブスクリプションキーを確認する
Azure PortalにてAPI Management services→(Azure Learnの手順に沿って作成したインスタンス)→Subscriptions→+Add subscriptionをクリックします。
Nameに任意の名前を入力しSaveをクリックします。
作成したキーの右側の「・・・」をクリックしShow/hide keysをクリックすることでPrimary Keyを表示→メモします。
テスト
Developer portalにてAPIs→(Azure Learnの手順に沿って作成したAPI名)をクリックします。
GET ProductDetails→Try itの順でクリックします。
次のように入力します。
- Subscription key: 先の手順でメモしたサブスクリプションキー
- Parameters: id=1を指定
- oauth2: authorization_codeを選択しログインする
準備ができたら「Send」をクリックします。200 OKが表示されたら成功です。
まとめ
想像以上に長い手順だったと思います。お疲れ様でした。
APIにアクセス制限ポリシーをカスタマイズすることでJWTの中に埋め込まれた情報をFunctionsに渡せそうに見えるのですが、そのあたりはまた次回検証したいと思います。