メインコンテンツまでスキップ

Azure AD 認可情報を用いてフロントエンドアプリから Azure Functions を呼び出す

· 約6分
ks6088ts

Azure AD 認可情報を用いてフロントエンドアプリから Azure Functions を呼び出すハンズオンをしました。 参考になった情報のリンクをまとめます。

Azure AD 認可情報を用いてフロントエンドアプリから Azure Functions を呼び出す

Azure App Service 上にデプロイされた React 製のフロントエンドアプリから、Azure Functions を呼び出すサンプルを提供します。

本アプリは以下の要求事項を満たします。

  • フロントエンドアプリは Azure AD 認証を通すことを必須とする
  • Azure Functions は Azure AD 認証を必須とする
  • フロントエンドアプリの Azure AD 認証を通したユーザは、追加の認証を通すことなく、フロントエンドアプリの認証情報を用いて Azure Functions を呼び出すことができる
  • フロントエンドアプリ、Azure Functions 双方は Azure App Service の組み込み認証を利用し、認証処理の一切をアプリケーションコードに組み込む必要がない

ハンズオン

React アプリの作成

以下の記事を参考に、create-react-app を用いてフロントエンドアプリを作成します。

# create SPA app in spa directory
npx create-react-app react-ts --template typescript

# install dependencies
cd react-ts && npm install

# build an app
npm run build

# run an app
npm start

React アプリのデプロイ

以下の記事を参考に、App Service に React のフロントエンドアプリをデプロイします。

# アプリのビルド
npm run build

# build 実行で生成された静的サイトが格納されたディレクトリに移動
cd build

# Azure CLI で Azure App Service にデプロイする
randomIdentifier="1128"

name="react$randomIdentifier"
resourceGroup="$name-rg"
location="eastus"

# create resource group
az group create --name $resourceGroup --location $location

# deploy web app
az webapp up \
--resource-group $resourceGroup \
--plan "$name-plan" \
--name $name \
--location $location \
--sku FREE \
--html

フロントエンドアプリから Azure AD 認証を必要とする API を呼び出す

アプリ コードでのトークンの取得 に記載があるように、AAD 認証済クライアントは、/.auth/me にリクエストすることでアクセストークンを取得できます。

API コールのためにフロントエンドアプリコードで必要な実装は、以下の 2 点です。

  • /.auth/me にリクエストして access_token を取得
  • 取得した access_token をヘッダに追加して Azure Functions を呼び出す

実証実験のためのサンプルコードは以下の通りです。簡略化のためエラーハンドリング等は省略しています。

async function getToken(url: string) {
const res = await fetch(url);
const json = await res.json();
if (!json) {
throw ReferenceError('Empty response');
}

console.log(`json: ${JSON.stringify(json)}`);
return json[0]['access_token'];
}

async function callApi(url: string, token: string) {
await fetch(url, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((resp) => {
resp.text().then(function (respStr) {
console.log(`success: ${respStr}`);
});
})
.catch((error) => {
console.log(error);
});
}

export async function main() {
const authUrl = 'https://YOURAPP.azurewebsites.net/.auth/me';
const token = await getToken(authUrl);
console.log(`token: ${token}`);

const apiUrl =
'https://YOURFUNC.azurewebsites.net/api/YOURFUNC?code=YOURCODE';
callApi(apiUrl, token);
}

上記実装を追加した Pull Request はこちらです。

support api call #4

動作確認したサンプルコードはこちらで公開しています。

github.com/ks6088ts-labs/react-ts

AAD 認証の設定

  • App Service (=フロントエンドアプリ)
    • App Service > 認証 に Microsoft の ID プロバイダーを登録
      • 発行者の URL を空欄にする
    • Azure AD > 管理 > API のアクセス許可 に API (=Azure Functions) のアクセス許可を追加
    • loginParameters 設定を Azure Resource Explorer で書き換える。(Azure Functions のアプリケーション ID を追記)
    • 参考: Accessing Microsoft Graph with App Service Auth V2
  • Azure Functions (=API)
    • 関数アプリ > 設定 > 認証 の ID プロバイダーに Microsoft を追加
      • 発行者の URL を空欄にする
    • Azure AD > 管理 > API のアクセス許可 に API (=Azure Functions) のアクセス許可を追加

CORS 設定

最新のブラウザーでは、クライアントで悪意のあるコードが実行されるのを防ぐために、Web アプリケーションから別のドメインで実行されるリソースへの要求をブロックします。

今回は、App Service にデプロイした静的サイトのドメインからのリクエストを許可するため、Azure Functions の CORS 設定を変更します。

具体的には、Azure ポータルにて、関数アプリ > API > CORS を開いて、許可される元のドメインに https://YOURAPP.azurewebsites.net を追加するだけです。

MSAL を使う場合

実装に際しては上記ドキュメントをご参照ください。 MSAL ライブラリをアプリケーション側に組み込むため以下の対応が必要になります。

  • リソース変更の度に ID 設定変更を入れてフロントエンドアプリをリビルドする
  • 依存ライブラリの更新があったら都度更新する