events
チュートリアル: バックエンド API を介して App Service から Microsoft Graph への認証のフローを行う
フロントエンド アプリのユーザー資格情報を受け入れるようにバックエンド アプリ サービスを作成して構成した後、その資格情報をダウンストリームの Azure サービスと交換する方法について説明します。 これにより、ユーザーはフロントエンドの App Service にサインインし、その資格情報をバックエンドの App Service に渡してから、同じ ID で Azure サービスにアクセスできます。
このチュートリアルでは、以下の内容を学習します。
- ダウンストリームの Azure サービスにスコープが設定されたトークンを提供するように、バックエンド認証アプリを構成する
- JavaScript コードを使って、サインインしているユーザーのアクセス トークンを、ダウンストリームのサービスの新しいトークンと交換します。
- JavaScript コードを使ってダウンストリームのサービスにアクセスします。
このチュートリアルを始める前に、前の「チュートリアル: セキュリティで保護された JavaScript アプリからユーザーとして Microsoft Graph にアクセスする」を済ませ、ただしそのチュートリアルの最後でリソースを削除しないでください。 このチュートリアルでは、2 つのアプリ サービスとそれに対応する認証アプリがあることを前提としています。
前のチュートリアルでは、Azure CLI のシェルとして Azure Cloud Shell を使いました。 このチュートリアルでは、引き続きそれを使います。
このチュートリアルでは、フロントエンド アプリによって提供されたユーザー資格情報をバックエンド アプリに渡し、さらに Azure サービスにそれを渡す方法について説明します。 このチュートリアルでのダウンストリーム サービスは Microsoft Graph です。 ユーザーの資格情報は、Microsoft Graph からプロファイルを取得するために使われます。
このアーキテクチャでユーザーが Microsoft Graph の情報を取得するための認証フロー:
前のチュートリアルで説明した内容:
- ID プロバイダーとして Active Directory を使うように構成されたフロントエンド App Service にユーザーをサインインさせます。
- フロントエンド App Service は、ユーザーのトークンをバックエンド App Service に渡します。
- バックエンド アプリは、フロントエンドが API 要求を行えるようにセキュリティで保護されています。 ユーザーのアクセス トークンには、バックエンド API の対象ユーザーと、
user_impersonation
のスコープが設定されています。 - バックエンド アプリの登録には、スコープを
User.Read
とする Microsoft Graph が既に含まれます。 これは、すべてのアプリ登録に既定で追加されます。 - 前のチュートリアルの最後では、Graph が接続されていないため、"偽" のプロファイルがフロントエンド アプリに返されました。
このチュートリアルでは、そのアーキテクチャを拡張します。
- バックエンド アプリのユーザーの同意画面をバイパスするため、管理者の同意を付与します。
- フロントエンド アプリから送信されたアクセス トークンを、Microsoft Graph に必要なアクセス許可を持つアクセス トークンに変換するよう、アプリケーションのコードを変更します。
- バックエンド アプリに Microsoft Graph などのダウンストリーム Azure サービスのスコープを持つ新しいトークンとトークンを交換させるコードを提供します。
- バックエンド アプリに新しいトークンを使用して現在の認証ユーザーとしてダウンストリーム サービスにアクセスさせるコードを提供します。
az webapp up
を使ってバックエンド アプリを再デプロイします。- このチュートリアルの最後では、Graph が接続されているため、"実際" のプロファイルがフロントエンド アプリに返されます。
このチュートリアルでは、次のことは行いません。
- 前のチュートリアルからフロントエンド アプリを変更する。
User.Read
が既定ですべての認証アプリに追加されるため、バックエンド認証アプリのスコープのアクセス許可を変更する。
前のチュートリアルでは、ユーザーがフロントエンド アプリにサインインすると、ユーザーの同意を求めるポップアップが表示されました。
このチュートリアルでは、Microsoft Graph からユーザー プロファイルを読み取るため、バックエンド アプリでは、サインインしているユーザーのアクセス トークンを、Microsoft Graph に対する必要なアクセス許可を持つ新しいアクセス トークンと、交換する必要があります。 ユーザーは、バックエンド アプリに直接接続されていないため、対話形式で同意画面にアクセスすることはできません。 これを回避するには、管理者の同意を付与するように、Microsoft Entra ID でバックエンド アプリのアプリ登録を構成する必要があります。 通常、この設定変更は Active Directory 管理者が行います。
Azure portal を開き、バックエンド App Service の調査を検索します。
[設定] -> [認証] セクションを見つけます。
認証アプリにアクセスするための ID プロバイダーを選びます。
認証アプリで、[管理] -> [API のアクセス許可] を選びます。
[既定のディレクトリに管理者の同意を与えます] を選択します。
ポップアップ ウィンドウで、[はい] を選んで同意を確認します。
[状態] 列に [Granted for Default Directory] (既定のディレクトリに付与) と表示されていることを確認します。 この設定では、バックエンド アプリはサインインしているユーザーに同意画面を表示する必要がなく、アクセス トークンを直接要求できます。 アプリ登録が作成される既定のスコープは
User.Read
であるため、サインインしているユーザーはそのスコープ設定にアクセスできます。
前のチュートリアルでは、Azure portal で ID プロバイダーを構成することによってのみ認証が提供されたため、バックエンド アプリでは認証に npm パッケージは必要ありませんでした。 このチュートリアルでは、サインインしているユーザーのバックエンド API 用のアクセス トークンを、スコープ内の Microsoft Graph でのアクセス トークンと交換する必要があります。 この交換では、App Service 認証は使われなくなりますが、Microsoft Entra ID と MSAL.js を直接使うため、この交換は 2 つのライブラリで行われます。
- @azure/MSAL-node - トークンを交換します
- @microsoft/microsoft-graph-client - Microsoft Graph に接続します
Azure Cloud Shell を開き、サンプル ディレクトリのバックエンド アプリに移動します。
Azure CLIcd js-e2e-web-app-easy-auth-app-to-app/backend
Azure MSAL の npm パッケージをインストールします。
Azure CLInpm install @azure/msal-node
Microsoft Graph の npm パッケージをインストールします。
Azure CLInpm install @microsoft/microsoft-graph-client
このステップを完了するためのソース コードは用意されています。 次の手順を使ってそれを組み込みます。
./src/server.js
ファイルを開きます。ファイルの先頭にある次の依存関係のコメントを解除します。
JavaScriptimport { getGraphProfile } from './with-graph/graph';
同じファイルで、
graphProfile
変数のコメントを解除します。JavaScriptlet graphProfile={};
同じファイルで、
get-profile
ルート内の次のgetGraphProfile
行のコメントを解除して、Microsoft Graph からプロファイルを取得します。JavaScript// where did the profile come from profileFromGraph=true; // get the profile from Microsoft Graph graphProfile = await getGraphProfile(accessToken); // log the profile for debugging console.log(`profile: ${JSON.stringify(graphProfile)}`);
変更を保存します: Ctrl + s キー。
バックエンド アプリを再デプロイします。
Azure CLIaz webapp up --resource-group myAuthResourceGroup --name <back-end-app-name>
バックエンド API の対象ユーザー トークンを Microsoft Graph のトークンに変更するには、バックエンド アプリでテナント ID を検索し、MSAL.js 構成オブジェクトの一部としてそれを使う必要があります。 バックエンド アプリは Microsoft を ID プロバイダーとして構成されているので、テナント ID と他のいくつかの必要な値は App Service のアプリ設定に既に存在します。
次のコードは、サンプル アプリで既に提供されています。 開発者は、この同じ機能を必要とする他のアプリの構築に、この作業を適用できるよう、それがそこにある理由と、その動作方法を理解しておく必要があります。
./backend/src/with-graph/auth.js
ファイルを開きます。getTenantId()
関数を確認します。JavaScriptexport function getTenantId() { const openIdIssuer = process.env.WEBSITE_AUTH_OPENID_ISSUER; const backendAppTenantId = openIdIssuer.replace(/https:\/\/sts\.windows\.net\/(.{1,36})\/v2\.0/gm, '$1'); return backendAppTenantId; }
この関数は、
WEBSITE_AUTH_OPENID_ISSUER
環境変数から現在のテナント ID を取得します。 ID は、正規表現を使って変数から解析されます。
引き続き
./backend/src/with-graph/auth.js
ファイルで、getGraphToken()
関数を確認します。MSAL.js 構成オブジェクトをビルドし、MSAL の構成を使って clientCredentialAuthority を作成します。 On-behalf-off 要求を構成します。 次に、acquireTokenOnBehalfOf を使って、バックエンド API のアクセス トークンを Graph のアクセス トークンと交換します。
JavaScript// ./backend/src/auth.js // Exchange current bearerToken for Graph API token // Env vars were set by App Service export async function getGraphToken(backEndAccessToken) { const config = { // MSAL configuration auth: { // the backend's authentication CLIENT ID clientId: process.env.WEBSITE_AUTH_CLIENT_ID, // the backend's authentication CLIENT SECRET clientSecret: process.env.MICROSOFT_PROVIDER_AUTHENTICATION_SECRET, // OAuth 2.0 authorization endpoint (v2) // should be: https://login.microsoftonline.com/BACKEND-TENANT-ID authority: `https://login.microsoftonline.com/${getTenantId()}` }, // used for debugging system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: true, logLevel: MSAL.LogLevel.Verbose, } } }; const clientCredentialAuthority = new MSAL.ConfidentialClientApplication(config); const oboRequest = { oboAssertion: backEndAccessToken, // this scope must already exist on the backend authentication app registration // and visible in resources.azure.com backend app auth config scopes: ["https://graph.microsoft.com/.default"] } // This example has App service validate token in runtime // from headers that can't be set externally // If you aren't using App service's authentication, // you must validate your access token yourself // before calling this code try { const { accessToken } = await clientCredentialAuthority.acquireTokenOnBehalfOf(oboRequest); return accessToken; } catch (error) { console.log(`getGraphToken:error.type = ${error.type} ${error.message}`); } }
フロントエンド アプリケーションにサインインしたユーザーとして Microsoft Graph にアクセスするための変更には、次のものが含まれます。
- 必要なスコープ
User.Read
でダウンストリーム サービス Microsoft Graph への API アクセス許可を持つ Active Directory アプリ登録の構成。 - バックエンド アプリのユーザーの同意画面をバイパスするため、管理者の同意を付与します。
- フロントエンド アプリから送信されたアクセス トークンを、ダウンストリーム サービス Microsoft Graph に必要なアクセス許可を持つアクセス トークンに変換するよう、アプリケーションのコードを変更します。
コードに Microsoft Graph の正しいトークンが設定されたので、それを使って Microsoft Graph に対するクライアントを作成し、ユーザーのプロファイルを取得します。
./backend/src/graph.js
を開きますgetGraphProfile()
関数で、トークンを取得し、トークンから認証されたクライアントを取得した後、プロファイルを取得します。JavaScript// import graph from "@microsoft/microsoft-graph-client"; import { getGraphToken } from "./auth.js"; // Create client from token with Graph API scope export function getAuthenticatedClient(accessToken) { const client = graph.Client.init({ authProvider: (done) => { done(null, accessToken); } }); return client; } export async function getGraphProfile(accessToken) { // exchange current backend token for token with // graph api scope const graphToken = await getGraphToken(accessToken); // use graph token to get Graph client const graphClient = getAuthenticatedClient(graphToken); // get profile of user const profile = await graphClient .api('/me') .get(); return profile; }
ブラウザーでフロントエンド Web サイトを使います。 URL は
https://<front-end-app-name>.azurewebsites.net/
という形式です。 トークンの有効期限が切れている場合は、更新が必要になることがあります。[
Get user's profile
] を選択します。 これにより、ベアラー トークンの認証がバックエンドに渡されます。バックエンドは、アカウントの "実際" の Microsoft Graph プロファイルで応答します。
前の手順では、リソース グループ内に Azure リソースを作成しました。
Cloud Shell で次のコマンドを実行して、リソース グループを削除します。 このコマンドの実行には、少し時間がかかる場合があります。
Azure CLIaz group delete --name myAuthResourceGroup
認証アプリのクライアント ID を使います。これは、バックエンド アプリとフロントエンド アプリの
Enable authentication and authorization
セクションで以前に確認し、メモしておいたものです。フロントエンド アプリとバックエンド アプリの両方のアプリ登録を削除します。
Azure CLI# delete app - do this for both frontend and backend client ids az ad app delete <client-id>
このエラー CompactToken parsing failed with error code: 80049217
は、バックエンド App Service が Microsoft Graph のトークンを返す権限を持たないことを意味します。 このエラーは、アプリの登録に User.Read
アクセス許可がないために発生します。
このエラー AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resource
は、バックエンド認証アプリが管理者の同意用に構成されていないことを意味します。 エラーはバックエンド アプリのログで示されるため、フロントエンド アプリケーションは、フロントエンド アプリに自分のプロファイルが表示されなかった理由をユーザーに伝えることができません。
このチュートリアルでは、Microsoft Graph に対して認証された API アプリを示していますが、同じ一般的な手順を適用して、ユーザーの代わりに任意の Azure サービスにアクセスできます。
- フロントエンド アプリケーションに変更はありません。 バックエンドの認証アプリの登録とバックエンド アプリのソース コードを変更するだけです。
- バックエンド API をスコープとするユーザーのトークンを、アクセスしたいダウンストリーム サービスへのトークンと交換します。
- ダウンストリーム サービスの SDK でトークンを使って、クライアントを作成します。
- ダウンストリームのクライアントを使って、サービスの機能にアクセスします。
その他のリソース
トレーニング
モジュール
Retrieve Microsoft 365 data for Microsoft Teams apps using Microsoft Graph - Training
Learn how to authenticate users with Microsoft identity platform, configure permissions, and retrieve user data for your Microsoft Teams app using the Microsoft Graph API.
認定資格
Microsoft Certified: Identity and Access Administrator Associate - Certifications
ID ソリューションの現代化、ハイブリッド ソリューションの実装、ID ガバナンスの実装を行う Microsoft Entra ID の機能を実証します。