はじめに
構成
- フロントエンドはReactで作成し、AzureWebAppsにdeploy
- RestAPIはPythonで作成し、AzureWebAppsにdeploy
- フロントエンドとRestAPIのAzureWebAppsは別リソース
- 認証・認可は、AzureADを使用
やりたいこと
- AADで認証済みのユーザーのみウェブアプリにアクセスしてRestAPIも実行できる
この記事では扱わないこと
- WebAppsへのアプリのdeployは出来ている前提とする
- Static Web Appsは使わない
- API Managementは使わない
やったこと
フロントエンド側に認証設定
- フロントエンド側のWebAppsのコンソールからApp Service認証を「オン」にして、Azure Active Directoryを選択します
- 細かい設定は後回しにして、簡易モードで認証設定します
単純な認証は、これだけでOKです。
ブラウザからWebアプリを開くと、AADでの認証を求められます。
RestAPI側に認証設定
- フロントエンド側同様に、RestAPI側もWebAppsのコンソールからApp Service認証を「オン」にして、Azure Active Directoryを選択します
- 詳細モードに切り替えて、クライアントID、発行者のURL、クライアントシークレットを入力してください
とりあえず、これで、コンソールから認証の設定ができました。
APIを呼び出す
- 認証を設定した状態ですと、何もしなければAPI呼び出しが401エラーになります
-
access_token
をAuthorization
ヘッダーにつけることで、APIを呼び出すことが出来ます -
access_token
は、フロントエンド側で認証後に.auth/me
にアクセスすることで取得可能です
access_tokenを
更新する
-
.auth/me
から取れるtokenは、残念ながら有効期限が切れても更新されません - 更新するには、
.auth/refresh
を呼び出してください - ただし、何も設定をしないと、うまく更新されてくれませんでした。下記の設定が必要だと思われます。
- Azure Resource Explore( https://resources.azure.com ) を開く
- フロントエンド側のWeb Appsのリソースの認証設定にたどり着く
subscriptions > ** <subscription_name** > resourceGroups > **_ <resource_group_name> ** > providers > Microsoft.Web > sites > ** <app_name>** > config > authsettings
- additionalLoginParamsを下記のように書き換える。
<app_id>
はAADのアプリクライアントID"additionalLoginParams": ["response_type=code id_token", "resource=<app_id>"]
- このあたり、よく分かってないので間違えているかもしれません。Azureのドキュメントを貼っておくので、そちらを読み解いてもらえればと。
431エラーを回避する
- ここまでで問題なく動けばOKですが、431エラーが出ることがあります。
- 認証設定によりヘッダーが追加されて、ヘッダー長が長すぎることが原因です。
- 環境変数で
WEBSITE_AUTH_DISABLE_IDENTITY_FLOW=true
を設定することで回避出来ます。 - これも正直良くわかってないです。Azure OSS Developer Supportに記事があったので、そちらを参照してください。
まとめ
AzureWebApps上に構築したSPA+REST APIのウェブアプリにAADで認証を設定できた
必要な設定
- コンソールからフロントエンド側のWebAppsに認証を設定
- コンソールからRestAPI側のWebAppsにも認証を設定
- https://resources.azure.com から、トークンの更新の設定
- 環境変数に
WEBSITE_AUTH_DISABLE_IDENTITY_FLOW=true
をセット
APIを呼び出す時にやること
-
.auth/refresh
を呼び出してtokenを更新 -
.auth/me
を呼び出してaccess_tokenを取得 - access_tokenを使用して、APIを呼び出す
お試しで書いてみたAPI呼び出しのコードです。