次の方法で共有


チュートリアル: Azure App Service でユーザーをエンド ツー エンドで認証および承認する

Azure App Service では、高度にスケーラブルな自己適用型の Web ホスティング サービスを提供しています。 App Service には、ユーザー認証と承認のサポートが組み込まれています。 このチュートリアルでは、App Service の認証と承認を使用してアプリケーションをセキュリティで保護する方法を示します。 ビューのフロントエンドで Express.js を使用します。 App Service の認証と承認では、すべての言語ランタイムがサポートされます。 このチュートリアルに従って、優先する言語に適用する方法について説明します。

Azure App Service は、Linux オペレーティング システムを使用して、高度にスケーラブルで自己修正型の Web ホスティング サービスを提供します。 App Service には、ユーザー認証と承認のサポートが組み込まれています。 このチュートリアルでは、App Service の認証と承認を使用してアプリケーションをセキュリティで保護する方法を示します。 ビューのフロントエンドで Express.js を使用します。 App Service の認証と承認では、すべての言語ランタイムがサポートされます。 このチュートリアルに従って、優先する言語に適用する方法について説明します。

この手順の認証は、Azure App Service によるホスティング プラットフォーム レイヤーで提供されます。 フロントエンド アプリとバックエンド アプリをデプロイし、この Web アプリが正常に使用されるように認証を構成する必要があります。

概念図は、Web ユーザーからフロントエンド アプリからバックエンド アプリへの認証フローを示しています。

このシナリオを完了したら、次のチュートリアルに進み、認証されたユーザーとして Azure サービスに接続する方法を学習します。 一般的なシナリオには、特定の能力または特定のテーブルやファイルへのアクセス権を持つユーザーとして、Azure Storage またはデータベースにアクセスすることが含まれます。

このチュートリアルでは、次の操作を行います。

  • 組み込みの認証および承認を有効にする
  • 未認証の要求に対してアプリをセキュリティで保護する
  • ID プロバイダーとして Microsoft Entra ID を使用する
  • サインインしたユーザーの代わりにリモート アプリにアクセスする
  • トークン認証を使用して、サービス間呼び出しをセキュリティで保護する
  • サーバー コードのアクセス トークンを使用する

前提条件

Azure アカウントをお持ちでない場合は、開始する前に無料アカウントを作成してください。

  • Azure Cloud Shell で Bash 環境を使用します。 詳細については、「Azure Cloud Shell の概要」を参照してください。

  • CLI リファレンス コマンドをローカル環境で実行したい場合は、Azure CLI をインストールします。 Windows または macOS で実行している場合は、Docker コンテナーで Azure CLI を実行することを検討してください。 詳細については、「Docker コンテナーで Azure CLI を実行する方法」を参照してください。

    • ローカル インストールを使用する場合は、az login コマンドを使用して Azure CLI にサインインします。 認証プロセスを完了するには、ターミナルに表示される手順に従います。 その他のサインイン オプションについては、「 Azure CLI を使用した Azure への認証」を参照してください。

    • 初回使用時に求められたら、Azure CLI 拡張機能をインストールします。 拡張機能の詳細については、「Azure CLI で拡張機能を使用および管理する」を参照してください。

    • インストールされているバージョンと依存ライブラリを調べるには、az version を実行します。 最新バージョンにアップグレードするには、az upgrade を実行します。

ユーザー プロファイルを取得する

フロントエンド アプリは、バックエンド API を安全に使用するように構成されています。 フロントエンド アプリケーションは、ユーザーに Microsoft のサインインを提供し、ユーザーがバックエンドから 自分の偽 のプロファイルを取得できるようにします。 このチュートリアルでは、シナリオを完了する手順を単純化するために偽のプロファイルを使います。

フロントエンドでソース コードを実行する前に、App Service によって App Service x-ms-token-aad-access-token ヘッダーから認証済みのaccessTokenが挿入されます。 その後、フロントエンド ソース コードは、 accessToken にアクセスしてバックエンド サーバーに送信します。 フロントエンド サーバーは、バックエンド API に安全にアクセスするための bearerToken としてトークンを送信します。 バックエンド サーバーは、バックエンド ソース コードに渡す前に bearerToken を検証します。 バックエンド ソース コードが bearerTokenを受け取った後、それを使用できます。

このシリーズ の次のチュートリアル では、 bearerToken は、Microsoft Graph API にアクセスするためのスコープを持つトークンと交換されます。 Microsoft Graph API は、ユーザーのプロファイル情報を返します。

サンプル アプリケーションの複製

Azure Cloud Shell で次のコマンドを実行し、サンプル リポジトリをクローンします。

git clone https://github.com/Azure-Samples/js-e2e-web-app-easy-auth-app-to-app

アプリを作成して展開する

リソース グループ、Web アプリプラン、Web アプリを作成し、1 つの手順でデプロイします。

  1. frontend Web アプリ ディレクトリに移動します。

    cd js-e2e-web-app-easy-auth-app-to-app/frontend
    
  2. az webapp up コマンドを使用して、フロントエンド Web アプリを作成してデプロイします。 Web アプリ名はグローバルに一意である必要があります。 <front-end-app-name> を一意の名前に置き換えます。

    az webapp up --resource-group myAuthResourceGroup --name <front-end-app-name> --plan myPlan --sku FREE --os-type Windows --location "West Europe" --runtime "NODE:20LTS"
    
  3. backend Web アプリ ディレクトリに移動します。

    cd ../backend
    
  4. バックエンド Web アプリを同じリソース グループとアプリプランにデプロイします。 Web アプリ名はグローバルに一意である必要があります。 <back-end-app-name>を一意の文字と数字の文字列に置き換えます。

    az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> --plan myPlan --os-type Windows --location "West Europe" --runtime "NODE:20LTS"
    
  1. frontend Web アプリ ディレクトリに移動します。

    cd frontend
    
  2. az webapp up コマンドを使用して、フロントエンド Web アプリを作成してデプロイします。 Web アプリ名はグローバルに一意である必要があります。 <front-end-app-name>を一意の文字と数字の文字列に置き換えます。

    az webapp up --resource-group myAuthResourceGroup --name <front-end-app-name> --plan myPlan --sku FREE --location "West Europe" --os-type Linux --runtime "NODE:20-lts"
    
  3. backend Web アプリ ディレクトリに移動します。

    cd ../backend
    
  4. バックエンド Web アプリを同じリソース グループとアプリプランにデプロイします。 Web アプリ名はグローバルに一意である必要があります。 <back-end-app-name>を一意の文字と数字の文字列に置き換えます。

    az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> --plan myPlan --sku FREE --location "West Europe" --runtime "NODE:16-lts"
    

アプリ設定の構成

フロントエンド アプリケーションは、API 要求のバックエンド アプリケーションの URL を認識している必要があります。 次の Azure CLI コマンドを使って、アプリの設定を構成します。 URL は https://<back-end-app-name>.azurewebsites.netする必要があります。

az webapp config appsettings set --resource-group myAuthResourceGroup --name <front-end-app-name> --settings BACKEND_URL="https://<back-end-app-name>.azurewebsites.net"

フロントエンドがバックエンドを呼び出す

フロントエンド アプリを参照し、バックエンドから のプロファイルを返します。 このアクションは、フロントエンドがバックエンドからプロファイルを正常に要求し、バックエンドがプロファイルを返していることを検証します。

  1. ブラウザーでフロントエンド Web アプリ ( https://<front-end-app-name>.azurewebsites.net) を開きます。

    認証が正常に完了した後のフロントエンド アプリケーションを示す Web ブラウザーのスクリーンショット。

  2. [ ユーザーのプロファイルの取得 ] リンクを選択します。

  3. バックエンド Web アプリから返された のプロファイルを表示します。

    サーバーから返された偽のプロファイルが表示されたブラウザーのスクリーンショット。

    withAuthentication の値が false の場合は、認証がまだ設定されて "いない" ことを示します。

認証を構成する

このセクションでは、2 つの Web アプリの認証と承認を有効にします。 このチュートリアルでは、ID プロバイダーとして Microsoft Entra ID を使用します。

また、フロントエンド アプリを次のように構成します。

  • フロントエンド アプリにバックエンド アプリへのアクセス権を付与する
  • 使用可能なトークンを返すように App Service を構成する
  • コードでトークンを使用する

詳細については、「App Services アプリケーションの Microsoft Entra 認証を構成する」を参照してください。

バックエンド アプリの認証と承認を有効にする

  1. Azure portal で、リソース グループを検索して選択します。

  2. [リソース グループ] でリソース グループを検索して選択します。 [ 概要] で、バックエンド アプリを選択します。

  3. バックエンド アプリの左側のメニューで、[設定]、[認証>、 [ID プロバイダーの追加] の順に選択します。

  4. [ ID プロバイダーの追加 ] ページで、 ID プロバイダーの場合は、 Microsoft と Microsoft Entra の ID を使用してサインインする Microsoft を選択します。

  5. クライアント シークレットの有効期限の値を選択します。

    バックエンド アプリの左側のメニューのスクリーンショット。認証/承認が選択され、右側のメニューで設定が選択されています。

  6. その他の値については、既定の設定をそのまま使用し、[追加] を選択 します

  7. [認証] ページが開きます。 Microsoft Entra アプリケーションのクライアント ID をメモ帳にコピーします。 この値は、後で必要になります。

    Microsoft Entra アプリを示す [Microsoft Entra Settings]\(Microsoft Entra の設定\) ウィンドウと、コピーするクライアント ID が表示されている [Microsoft Entra Applications]\(Microsoft Entra アプリケーション\) ウィンドウのスクリーンショット。

ここで停止すると、App Service の認証と承認によりセキュリティが確保された自己完結型アプリが得られます。 以降のセクションでは、認証されたユーザーをフロントエンドからバックエンドに フロー することで、複数のアプリ ソリューションをセキュリティで保護する方法について説明します。

フロントエンド アプリの認証と承認を有効にする

  1. Azure portal で、リソース グループを検索して選択します。

  2. [リソース グループ] でリソース グループを検索して選択します。 [ 概要] で、フロントエンド アプリを選択します。

  3. フロントエンド アプリの左側のメニューで、 設定>認証を選択し、[ ID プロバイダーの追加] を選択します。

  4. [ ID プロバイダーの追加 ] ページで、 ID プロバイダーの場合は、 Microsoft と Microsoft Entra の ID を使用してサインインする Microsoft を選択します。

  5. クライアント シークレットの有効期限の値を選択します。 その他の値については、既定の設定をそのまま使用し、[追加] を選択 します

  6. [認証] ページが開きます。 Microsoft Entra アプリケーションのクライアント ID をメモ帳にコピーします。 この値は、後で必要になります。

フロントエンド アプリにバックエンド アプリへのアクセス権を付与する

両方のアプリに対する認証と承認を有効にしました。 認証を完了するには、次の 3 つのことを行う必要があります。

  • フロントエンド アプリにバックエンド アプリへのアクセス権を付与する
  • 使用可能なトークンを返すように App Service を構成する
  • コードでトークンを使用する

ヒント

エラーが発生し、アプリの認証/承認設定を再構成した場合、トークン ストア内のトークンが新しい設定から再生成されない可能性があります。 トークンが再生成されるようにするには、サインアウトしてアプリにサインインし直す必要があります。 1 つの方法は、ブラウザーをプライベート モードで使用することです。 アプリの設定を変更した後、ブラウザーをプライベート モードで閉じてから再度開きます。

このセクションでは、ユーザーに代わって、フロントエンド アプリにバックエンド アプリへのアクセス権を付与します。 技術的には、フロントエンドの AD アプリケーション に、ユーザーの代わりにバックエンドの AD アプリケーション にアクセスするアクセス許可を付与します。

  1. フロントエンド アプリの [認証 ] ページの [ ID プロバイダー] で、フロントエンド アプリ名を選択します。 このアプリの登録は自動的に生成されました。

  2. 左側のメニューの [管理>API アクセス許可 ] を選択します。

  3. [アクセス許可の追加] を選択し、[自分の API]><back-end-app-name> を選択します。

  4. バックエンド アプリの [API アクセス許可の要求 ] ページで、[ 委任されたアクセス許可user_impersonation] を選択し、[ アクセス許可の追加] を選択します。

    [委任されたアクセス許可]、user_impersonation、および [アクセス許可の追加] ボタンが選択されているところを示す、[API アクセス許可の要求] ページのスクリーンショット。

使用可能なアクセス トークンを返すように App Service を構成する

フロントエンド アプリには、サインインしているユーザーとしてバックエンド アプリにアクセスするために必要なアクセス許可が付与されました。 このセクションでは、バックエンドにアクセスするための使用可能なアクセス トークンを提供するように App Service の認証と承認を構成します。 この手順では、バックエンドのクライアント ID が必要です。この ID は、 バックエンド アプリの認証と承認を有効にするからコピーしたものです。

Cloud Shell で、フロントエンド アプリで次のコマンドを実行して、認証設定identityProviders.azureActiveDirectory.login.loginParametersscope パラメーターを追加します。 <front-end-app-name><back-end-client-id> を置き換えます。

az extension add --name authV2
authSettings=$(az webapp auth show -g myAuthResourceGroup -n <front-end-app-name>)
authSettings=$(echo "$authSettings" | jq '.properties' | jq '.identityProviders.azureActiveDirectory.login += {"loginParameters":["scope=openid offline_access api://<back-end-client-id>/user_impersonation"]}')
az webapp auth set --resource-group myAuthResourceGroup --name <front-end-app-name> --body "$authSettings"

コマンドは、他のカスタム スコープと共に loginParameters プロパティを追加します。 要求するスコープの説明を次に示します。

  • openid は、既に既定で App Service によって要求されています。 詳細については、「 OpenID Connect スコープ」を参照してください。
  • トークンを更新する場合に備えて、便宜上、offline_accessがここに含まれています。
  • api://<back-end-client-id>/user_impersonation は、バックエンド アプリの登録で公開されている API です。 これは、トークン対象ユーザーとしてバックエンド アプリを含む JWT を提供するスコープ です

ヒント

  • Azure portal で api://<back-end-client-id>/user_impersonation スコープを表示するには、バックエンド アプリの [認証 ] ページに移動し、[ ID プロバイダー] の下にあるリンクを選択し、左側のメニューで [ API の公開 ] を選択します。
  • 代わりに Web インターフェイスを使用して必要なスコープを構成するには、「 認証トークンの更新」を参照してください。
  • スコープによっては、管理者またはユーザーの同意が必要な場合があります。 この要件により、ユーザーがブラウザーでフロントエンド アプリにサインインしたときに同意要求ページが表示されます。 この同意ページを回避するには、[ API の公開 ] ページで、フロントエンドのアプリ登録を承認されたクライアント アプリケーションとして追加します。 [ クライアント アプリケーションの追加] を選択し、フロントエンドのアプリ登録のクライアント ID を指定します。

これでアプリの構成は完了です。 これで、フロントエンドは適切なアクセス トークンを使用してバックエンドにアクセスする準備ができました。

他のプロバイダー用にアクセス トークンを構成する方法については、「ID プロバイダー トークンの更新」を参照してください。

フロントエンド App Service からのみトークンを受け入れるようにバックエンド App Service を構成する

また、フロントエンド App Service からのトークンのみを受け入れるようにバックエンド App Service を構成する必要があります。 この構成を行わないと、フロントエンドからバックエンドにトークンを渡すと 、403: 禁止エラーが発生 します。

この方法は、前の手順で使用したのと同じ Azure CLI プロセスを使用して実装できます。

  1. フロントエンド App Service の appId を取得します。 この値は、フロントエンド App Service の [認証 ] ページで取得できます。

  2. <back-end-app-name><front-end-app-id>に置き換えて、次の Azure CLI を実行します。

authSettings=$(az webapp auth show -g myAuthResourceGroup -n <back-end-app-name>)
authSettings=$(echo "$authSettings" | jq '.properties' | jq '.identityProviders.azureActiveDirectory.validation.defaultAuthorizationPolicy.allowedApplications += ["<front-end-app-id>"]')
az webapp auth set --resource-group myAuthResourceGroup --name <back-end-app-name> --body "$authSettings"

フロントエンドが認証されたバックエンドを呼び出す

フロントエンド アプリは、適切な user_impersonation スコープを持つユーザーの認証をバックエンドに渡す必要があります。 以下の手順では、この機能のサンプルで提供されているコードを確認します。

フロントエンド アプリのソース コードを表示します。

  1. フロントエンド App Service によって挿入された x-ms-token-aad-access-token ヘッダーを使用して、プログラムによってユーザーの accessToken を取得します。

    // ./src/server.js
    const accessToken = req.headers['x-ms-token-aad-access-token'];
    
  2. bearerToken 値として Authentication ヘッダーの accessToken を使います。

    // ./src/remoteProfile.js
    // Get profile from backend
    const response = await fetch(remoteUrl, {
        cache: "no-store", // no caching -- for demo purposes only
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${accessToken}`
        }
    });
    if (response.ok) {
        const { profile } = await response.json();
        console.log(`profile: ${profile}`);
    } else {
        // error handling
    }
    

    このチュートリアルでは、シナリオを簡単にするために "偽の" プロファイルを返します。 このシリーズの 次のチュートリアル では、Microsoft Graph などのダウンストリーム Azure サービスのスコープを使用して、バックエンド bearerToken を新しいトークンと交換する方法を示します。

バックエンドがプロファイルをフロントエンドに返す

フロントエンドからの要求が承認されていない場合、バックエンド App Service は、要求がアプリケーション コードに到達する 前に 、401 HTTP エラー コードで要求を拒否します。 バックエンド コードに達すると、承認されたトークンが含まれているため、 bearerToken を抽出して accessTokenを取得します。

バックエンド アプリのソース コードを表示します。

// ./src/server.js
const bearerToken = req.headers['Authorization'] || req.headers['authorization'];

if (bearerToken) {
    const accessToken = bearerToken.split(' ')[1];
    console.log(`backend server.js accessToken: ${!!accessToken ? 'found' : 'not found'}`);

    // TODO: get profile from Graph API
    // provided in next article in this series
    // return await getProfileFromMicrosoftGraph(accessToken)

    // return fake profile for this tutorial
    return {
        "displayName": "John Doe",
        "withAuthentication": !!accessToken ? true : false
    }
}

アプリを参照する

  1. ブラウザーでフロントエンド Web サイトを使用します。 URL は https://<front-end-app-name>.azurewebsites.net/ です。

  2. ブラウザーから、Web アプリへの認証が要求されます。 認証を完了します。

    アクセス許可を要求しているブラウザー認証ポップアップのスクリーンショット。

  3. 認証が完了すると、フロントエンド アプリケーションはアプリのホーム ページを返します。

    認証が正常に完了した後、フロントエンド アプリケーションが表示されている Web ブラウザーのスクリーンショット。

  4. [ ユーザーのプロファイルの取得] を選択します。 このアクションにより、ベアラー トークン内の認証がバックエンドに渡されます。

  5. バックエンドは、 のハードコーディングされたプロファイル名 ( John Doe) で応答します。

    バックエンド アプリから偽のプロファイルを正常に取得した後のフロントエンド アプリケーションを示す Web ブラウザーのスクリーンショット。

    withAuthenticationtrue は、認証が現在設定されていることを示します。

リソースをクリーンアップする

前の手順では、リソース グループ内に Azure リソースを作成しました。

  1. Cloud Shell で次のコマンドを実行して、リソース グループを削除します。 このコマンドの実行には、少し時間がかかる場合があります。

    az group delete --name myAuthResourceGroup
    
  2. 認証アプリのクライアント ID を使います。これは、バックエンド アプリとフロントエンド アプリの Enable authentication and authorization セクションで以前に確認し、メモしておいたものです。

  3. フロントエンド アプリとバックエンド アプリの両方のアプリ登録を削除します。

    # delete app - do this for both frontend and backend client ids
    az ad app delete <client-id>
    

よく寄せられる質問

この認証をローカルの開発マシンでテストするにはどうすればよいですか?

この手順の認証は、Azure App Service によるホスティング プラットフォーム レイヤーで提供されます。 同等のエミュレーターはありません。 フロントエンド アプリとバックエンド アプリをデプロイし、認証を使用するように各アプリの認証を構成する必要があります。

アプリに偽のプロファイルが表示されていない場合、どのようにデバッグすればよいですか?

フロントエンド アプリとバックエンド アプリの両方に /debug ルートがあり、このアプリケーションが のプロファイルを返さない場合に認証をデバッグするのに役立ちます。 フロントエンド デバッグ ルートには、検証する重要な要素が用意されています。

  • 環境変数:

    • BACKEND_URLhttps://<back-end-app-name>.azurewebsites.net として正しく構成されています。 末尾にはスラッシュまたはルートを含めないでください。
  • HTTP ヘッダー:

    • x-ms-token-* ヘッダーが挿入されます。
  • サインインしたユーザーの Microsoft Graph プロファイル名が表示されます。

  • トークンのフロントエンド アプリの スコープuser_impersonation。 スコープにこの値が含まれていない場合は、タイミングの問題である可能性があります。 Azure リソースでフロントエンド アプリのlogin パラメーターを確認します。 認証がレプリケートされるまで数分待ちます。

アプリケーションのソース コードは各 Web アプリに正しくデプロイされましたか?

  1. Web アプリ用の Azure portal で、 開発ツール>[Advanced Tools]、[ Go] の順に選択します。 この操作により、新しいブラウザー タブまたはウィンドウが開きます。

  2. 新しいブラウザー タブで、 ディレクトリの参照>サイト wwwroot を選択します。

  3. ディレクトリに次の項目があることを確認します。

    • package.json
    • node_modules.tar.gz
    • /src/index.js
  4. package.jsonname プロパティが Web 名と同じであることを確認します (frontendまたはbackend)。

  5. ソース コードを変更し、再デプロイする必要がある場合は、そのアプリの package.json ファイルがあるディレクトリから az webapp up コマンドを使用します。

アプリケーションは正しく起動しましたか?

どちらの Web アプリも、ホーム ページが要求されたときに何かを返すはずです。 Web アプリで /debug に到達できない場合、アプリは正しく起動していません。 その Web アプリのエラー ログを確認します。

  1. Web アプリ用の Azure portal で、 開発ツール>[Advanced Tools]、[ Go] の順に選択します。 この操作により、新しいブラウザー タブまたはウィンドウが開きます。
  2. 新しいブラウザー タブで、[ディレクトリの参照] >[ログのデプロイ] を選択します。
  3. 各ログを確認し、報告された問題を見つけます。

フロントエンド アプリはバックエンド アプリと通信できますか?

フロントエンド アプリはサーバー のソース コードからバックエンド アプリを呼び出すので、この動作はブラウザーのネットワーク トラフィックで確認できるものではありません。 バックエンド プロファイル要求の成功を確認するには、次の一覧を使用します。

  • バックエンド Web アプリは、フロントエンド アプリに到達した場合にエラーを返します。 到達しなかった場合、フロントエンド アプリは状態コードとメッセージを報告します。

    • 401: ユーザーは認証に正しく合格しませんでした。 このメッセージは、スコープが正しく設定されていないことを示している可能性があります。
    • 404: サーバーへの URL が、サーバーが持つルートと一致しません
  • バックエンド アプリのストリーミング ログを使用して、ユーザーのプロファイルのフロントエンド要求を行う際に監視します。 ソース コードには、エラーが発生した場所を特定するのに役立つ console.logを含むデバッグ情報があります。

フロントエンド トークンの有効期限が切れるとどうなりますか?

アクセス トークンは、しばらくすると有効期限が切れます。 アプリに対する再認証をユーザーに強制することなくアクセス トークンを更新する方法については、「Refresh identity provider tokens (ID プロバイダー トークンの更新)」を参照してください。

フロントエンド アプリにブラウザーベースのアプリがある場合、バックエンドと直接通信できますか?

この手法では、サーバー コードがクライアント ブラウザーで実行されている JavaScript コードにアクセス トークンを渡す必要があります。 ブラウザーでアクセス トークンを保護する方法がないため、この方法はお勧めしません。 現時点では、 バックエンドのフロントエンド パターンをお勧めします。

このチュートリアルの例に適用すると、フロントエンド アプリのブラウザー コードは、認証されたセッションで API 呼び出しをサーバー コードに中継局として行います。 フロントエンド アプリのサーバー コードは、ベアラー トークンとして x-ms-token-aad-access-token ヘッダー値を使用して、バックエンド アプリへの API 呼び出しを行います。 ブラウザー コードからサーバー コードへのすべての呼び出しは、認証されたセッションによって保護されます。

次のステップ

次のチュートリアルに進み、このユーザーの ID を使って Azure サービスにアクセスする方法を学習します。