1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

App Service上のEasy Auth使ったREST API呼出(Auth Code + PKCE)

Last updated at Posted at 2025-12-29

Azure App Service上に作ったREST APIにEasy Authを追加。
Python クライアントを作り、 OAuth 2.0 Authorization Code Flow with PKCE により Microsoft Entra ID で認証しています。

OAuth 2.0 Client Credintial Flow を使ったのは以下の記事。

実装イメージ

Pythonアプリを実行すると、以下のようなブラウザ認証をします。
image.png

認証通ると、ブラウザでは以下の画面のようになり、Tokenを取得できます。あとはToken取得してREST Call。プログラムは後ろに記載。
image.png

Steps

前提としてApp Serviceは以前作ったこれを流用。

1. Easy Auth設定

Portalのメニュー 設定 -> 認証で IDプロバイダーとして Microsoft を追加。
image.png
image.png

基本、上記のデフォルト設定でいいのですが、APIなので「認証されていない要求」は401の方がベターです。
image.png

2. アプリの登録

2.1. 登録

Entra のメニュー 管理 -> アプリの登録 で 「+新規登録」をクリック
image.png

リダイレクトURIに「パブリック クライアント/ネイティブ (モバイルとデスクトップ)」で"http://localhost"を入力しておきます。
image.png

2.2. パブリッククライアントフロー有効化

メニュー 管理 -> Authentication(Preview) で 設定タブで、「パブリック クライアントフローを許可する」を有効に設定して保存
image.png

今回はシークレット管理をしないので、パブリッククライアントフローを有効にしました。

2.3. APIのアクセス許可

メニュー 管理 -> APIのアクセス許可 で「+アクセス許可の追加」をクリック
image.png

すべてのAPIから自分のApp Serviceを選択し、「委任されたアクセス許可」を選び、「アクセス許可の追加」
image.png

「<テナント名>に管理者の同意を与えます。」をクリック
image.png

3. 許可されるトークン対象ユーザの追加

Portalの App Service 画面の メニュー 設定 -> 認証 で IDプロバイダー Microsoftを編集。
image.png

「許可されるトークン対象ユーザー」に先ほど登録したアプリケーション("api://")を追加。
image.png

追加する値はEntraのアプリケーションで概要にある「アプリケーション ID の URI」の値
image.png

4. APIを呼び出すPython Script

WSL の Ubuntu24.04でPython 3.13.11で実装。以下のパッケージ使用。

azure-identity: 1.25.1
httpx: 0.28.1

from azure.identity import InteractiveBrowserCredential
import httpx


tenant_id = "<tenant id>"
client_id = "<client id>" # Entraで登録したアプリのClient ID

credential = InteractiveBrowserCredential(tenant_id=tenant_id, client_id=client_id)

scope = "api://<app serviceのclient id>/user_impersonation"
token = credential.get_token(scope)
headers = {"Authorization": f"Bearer {token.token}"}

url = "https://<app service host>/hello"

async with httpx.AsyncClient() as client:
    response = await client.get(url, headers=headers)
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.text}")

scopeはEntraのメニュー 管理 -> APIの公開 から確認可能。api://<client id>/<スコープ名>。Python Client側のアプリケーションではなく、App Serviceのアプリケーションである点が要注意。
image.png

実行結果
Status Code: 200
Response: {"message":"hello, world"}

おまけ

認証除外パス追加

認証除外のパスを追加したい場合の処理。
az webapp auth update --excluded-pathを使った方法もありますが、こちらの方が安定していそう。

まずは、authsettingsを取得

SUB="<subscription-id>"
RG="<resource-group>"
APP="<app-name>"

az rest --method get \
  --url "https://management.azure.com/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Web/sites/$APP/config/authsettingsV2?api-version=2025-03-01" \
  > authsettingsV2.json

authsettingsV2.json の properties.globalValidation.excludedPaths に対象パスを入れます

authsettingsV2.json抜粋
  "properties": {
    "clearInboundClaimsMapping": "false",
    "globalValidation": {
      "excludedPaths": ["<対象パス>"],

最後に設定

az rest --method put \
  --url "https://management.azure.com/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Web/sites/$APP/config/authsettingsV2?api-version=2025-03-01" \
  --body @authsettingsV2.json

参考リンク

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?