シングル サインオンを使用する ASP.NET Office アドインを作成する
ユーザーは Office にサインインできます。Office Web アドインでは、このサインイン プロセスを利用して、ユーザーに 2 回目のサインインを要求することなく、アドインと Microsoft Graph に対するユーザーの承認を行うことができます。 この記事では、アドインでシングル サインオン (SSO) を有効にするプロセスについて説明します。
このサンプルでは、次の部分をビルドする方法を示します。
- Microsoft Excel、Word、またはPowerPointで読み込む作業ウィンドウを提供するクライアント側コード。 クライアント側コードは、Office JS API
getAccessToken()
を呼び出して、SSO アクセス トークンを取得してサーバー側の REST API を呼び出します。 - ASP.NET Coreを使用して単一の REST API
/api/files
を提供するサーバー側コード。 サーバー側コードでは、すべてのトークンの処理、認証、および承認 に Microsoft Authentication Library for .NET (MSAL.NET) が使用されます。
このサンプルでは、SSO と On-Behalf-Of (OBO) フローを使用して、正しいアクセス トークンを取得し、Microsoft Graph API を呼び出します。 このフローのしくみに慣れていない場合は、実行時の SSO のしくみ に関するページを参照してください。
前提条件
Visual Studio 2019 以降。
Visual Studio を構成するときの Office/SharePoint 開発 ワークロード。
Microsoft 365 サブスクリプション内のOneDrive for Businessに格納されているファイルとフォルダーが少なくともいくつかあります。
IdentityAPI 1.3 要件セットをサポートする Microsoft 365 のビルド。 Microsoft 365 開発者プログラムを通じて、開発者サンドボックスを含むMicrosoft 365 E5開発者サブスクリプションの対象となる場合があります。詳細については、「FAQ」を参照してください。 開発者サンドボックスには、この記事の後の手順でアプリの登録に使用できる Microsoft Azure サブスクリプションが含まれています。 必要に応じて、アプリの登録に別の Microsoft Azure サブスクリプションを使用できます。 Microsoft Azure で試用版サブスクリプションを取得します。
スタート プロジェクトをセットアップする
「Office Add-in ASPNET SSO」にあるリポジトリを複製するかダウンロードします。
注:
サンプルには 2 つのバージョンがあります。
- Begin フォルダーはスターター プロジェクトです。 SSO や承認に直接関連しない UI などの側面は、既に完了しています。 この記事で後述する各セクションでは、これを完成させるための手順を順に説明します。
- Complete フォルダーには、この記事のすべてのコーディング手順が完了した同じサンプルが含まれています。 完成したバージョンを使用するには、この記事の手順に従うだけですが、"Begin" を "Complete" に置き換え、「 クライアント側をコーディング する」と「 サーバー側のコーディング」のセクションをスキップします。
以降のアプリ登録手順のプレースホルダーには、次の値を使用します。
プレースホルダー | 値 |
---|---|
<add-in-name> |
Office-Add-in-ASPNET-SSO |
<fully-qualified-domain-name> |
localhost:44355 |
Microsoft Graph のアクセス許可 | profile, openid, Files.Read |
アドインを Microsoft ID プラットフォーム に登録する
Web サーバーを表すアプリ登録を Azure で作成する必要があります。 これにより、JavaScript のクライアント コードに対して適切なアクセス トークンを発行できるように、認証のサポートが可能になります。 この登録では、クライアントでの SSO と、Microsoft 認証ライブラリ (MSAL) を使用したフォールバック認証の両方がサポートされます。
Microsoft 365 テナントへの管理者資格情報を使用して、Azure portalにサインインします。 たとえば、「 MyName@contoso.onmicrosoft.com 」のように入力します。
[アプリの登録] を選択します。 アイコンが表示されない場合は、検索バーで "アプリの登録" を検索します。
[アプリの登録] ページが表示されます。
[新規登録] を選択します。
[アプリケーション登録] ページが表示されます。
[アプリケーションを登録] ページで、次のように値を設定します。
-
<add-in-name>
に [名前] を設定します。 - [サポートされているアカウントの種類] を[任意の組織のディレクトリ (任意の Azure AD ディレクトリ - マルチテナント)] と個人用 Microsoft アカウント (Skype、Xbox など) に設定します。
- [ リダイレクト URI] を 設定して、プラットフォーム の単一ページ アプリケーション (SPA) を使用し、URI を
https://<fully-qualified-domain-name>/dialog.html
します。
-
[登録] を選択します。 アプリケーション登録が作成されたことを示すメッセージが表示されます。
アプリケーション (クライアント) ID とディレクトリ (テナント) ID の値をコピーして保存します。 以降の手順では、それらの両方を使用します。
クライアント シークレットを追加する
アプリケーション パスワードと呼ばれることもあります。クライアント シークレットは、証明書の代わりにアプリが ID 自体に使用できる文字列値です。
左側のウィンドウで、[ 証明書 & シークレット] を選択します。 次に、[ クライアント シークレット ] タブで、[ 新しいクライアント シークレット] を選択します。
[ クライアント シークレットの追加] ウィンドウが表示されます。
クライアント シークレットの説明を追加します。
シークレットの有効期限を選択するか、カスタム有効期間を指定します。
- クライアント シークレットの有効期間は、2 年間 (24 か月) 以下に制限されます。 24 か月を超えるカスタム有効期間を指定することはできません。
- Microsoft では、有効期限の値を 12 か月未満に設定することをお勧めします。
[追加] を選択します。 新しいシークレットが作成され、値が一時的に表示されます。
重要
クライアント アプリケーション コードで使用するシークレットの値を記録します。 このウィンドウを離れた後、このシークレット値は 再び表示されることはありません 。
Web API を公開する
左側のウィンドウで、[ API の公開] を選択します。
[ API の公開 ] ウィンドウが表示されます。
[ 設定] を選択して、アプリケーション ID URI を生成します。
アプリケーション ID URI を設定するためのセクションは、生成されたアプリケーション ID URI を
api://<app-id>
フォームに表示します。アプリケーション ID URI を
api://<fully-qualified-domain-name>/<app-id>
に更新します。-
アプリケーション ID URI には、アプリ ID (GUID) が形式
api://<app-id>
で事前に入力されています。 - アプリケーション ID URI 形式は次のとおりです。
api://<fully-qualified-domain-name>/<app-id>
-
api://
と<app-id>
(GUID) の間にfully-qualified-domain-name
を挿入します。 たとえば、「api://contoso.com/<app-id>
」のように入力します。 - localhost を使用している場合は、形式を
api://localhost:<port>/<app-id>
する必要があります。 たとえば、「api://localhost:3000/c6c1f32b-5e55-4997-881a-753cc1d563b7
」のように入力します。
その他のアプリケーション ID URI の詳細については、「 アプリケーション マニフェスト識別子Uris 属性」を参照してください。
注:
ドメインを所有しているにもかかわらず、そのドメインが既に所有されているというエラーが表示される場合は、「クイック スタート: カスタム ドメイン名を Azure Active Directory に追加する」の手順に従って登録し、この手順を繰り返します。 (このエラーは、Microsoft 365 テナントの管理者の資格情報でサインインしていない場合にも発生する可能性があります。手順 2 を参照してください。サインアウトし、管理者の資格情報を使用してもう一度サインインし、手順 3. のプロセスを繰り返します)。
-
アプリケーション ID URI には、アプリ ID (GUID) が形式
スコープを追加する
[ API の公開 ] ページで、[ スコープの追加] を選択します。
[ スコープの追加] ウィンドウが開きます。
[ スコープの追加] ウィンドウで、スコープ の属性を指定します。 次の表は、
profile
、openid
、Files.ReadWrite
、およびMail.Read
のアクセス許可を必要とするおよび Outlook アドインの値の例を示しています。 アドインに必要なアクセス許可に合わせてテキストを変更します。フィールド 説明 値 スコープ名 スコープの名前。 一般的なスコープの名前付け規則は resource.operation.constraint
。SSO の場合、これは access_as_user
に設定する必要があります。同意できるユーザー 管理者の同意が必要かどうか、またはユーザーが管理者の承認なしで同意できるかどうかを決定します。 SSO とサンプルを学習するには、これを [管理者とユーザー] に設定することをお勧めします。
高い特権を持つアクセス許可 の場合にのみ、[管理者] を選択します。同意の表示名管理 スコープの目的の簡単な説明は、管理者にのみ表示されます。 Read/write permissions to user files. Read permissions to user mail and profiles.
同意の説明管理 管理者のみが表示するスコープによって付与されるアクセス許可の詳細な説明。 Allow Office to have read/write permissions to all user files and read permissions to all user mail. Office can call the app's web APIs as the current user.
ユーザー同意表示名 スコープの目的の簡単な説明。 [管理者とユーザーに同意できるユーザー] を設定した場合にのみ、ユーザーに表示されます。 Read/write permissions to your files. Read permissions to your mail and profile.
ユーザーの同意の説明 スコープによって付与されるアクセス許可のより詳細な説明。 [管理者とユーザーに同意できるユーザー] を設定した場合にのみ、ユーザーに表示されます。 Allow Office to have read/write permissions to your files, and read permissions to your mail and profile.
[状態] を [有効] に設定し、[スコープの追加] を選択します。
定義した新しいスコープがウィンドウに表示されます。
注:
テキスト フィールドのすぐ下に表示される [スコープ名] のドメイン部分は、たとえば
api://localhost:6789/c6c1f32b-5e55-4997-881a-753cc1d563b7/access_as_user
のように手順で設定された [アプリケーション ID URI] と自動的に一致し、最後に/access_as_user
が追加されます。[クライアント アプリケーションの追加] を選択します。
[ クライアント アプリケーションの追加] ウィンドウが表示されます。
[ クライアント ID ] に「
ea5a67f6-b6f3-4338-b240-c655ddc3cc8e
」と入力します。 この値は、すべての Microsoft Office アプリケーション エンドポイントを事前に承認します。 Microsoft Teams内で使用するときに Office を事前に承認する場合は、1fec8e78-bce4-4aaf-ab1b-5451cc387264
(Microsoft Teams デスクトップと Teams モバイル) と5e3ce6c0-2b1f-4285-8d4b-75ee78787346
(Teams on the web) を追加します。注:
ea5a67f6-b6f3-4338-b240-c655ddc3cc8e
ID は、次のすべてのプラットフォームで Office を事前に承認します。 または、何らかの理由で一部のプラットフォームで Office への承認を拒否する場合は、次の ID の適切なサブセットを入力することもできます。 その場合は、承認を保留するプラットフォームの ID を除外します。 これらのプラットフォーム上のアドインのユーザーは Web API を呼び出せなくなりますが、アドイン内の他の機能は引き続き機能します。-
d3590ed6-52b3-4102-aeff-aad2292ab01c
(Microsoft Office) -
93d53678-613d-4013-afc1-62e9e444a0a5
(Office on the web) -
bc59ab01-8403-45c6-8796-ac3ef710b3e3
(Outlook on the web)
-
[ 承認されたスコープ] で、[
api://<fully-qualified-domain-name>/<app-id>/access_as_user
] チェック ボックスをオンにします。[アプリケーションの追加] を選択します。
Microsoft Graph のアクセス許可を追加する
左側のウィンドウで、[ API アクセス許可] を選択します。
[API アクセス許可] ウィンドウが開きます。
[アクセス許可を追加] を選択します。
[ API のアクセス許可の要求 ] ウィンドウが開きます。
[Microsoft Graph] を選択します。
[委任されたアクセス許可] を選択します。
[ アクセス許可の選択 ] 検索ボックスで、アドインで必要なアクセス許可を検索します。 たとえば、Outlook アドインの場合は、
profile
、openid
、Files.ReadWrite
、Mail.Read
を使用できます。注:
User.Read
アクセス許可は既定でリストされています。 必要なアクセス許可のみを要求することをお勧めします。アドインで実際に必要ない場合は、このアクセス許可のチェック ボックスをオフにすることをお勧めします。表示される各アクセス許可のチェック ボックスをオンにします。 アクセス許可は、各アクセス許可を選択しても一覧に表示されません。 アドインに必要なアクセス許可を選択したら、[ アクセス許可の追加] を選択します。
[ テナント名] の [管理者の同意の付与] を選択します。 表示される確認のために [ はい ] を選択します。
アクセス トークンのバージョンを構成する
アプリで許容されるアクセス トークンのバージョンを定義する必要があります。 この構成は、Azure Active Directory アプリケーション マニフェストで行われます。
アクセス トークンのバージョンを定義する
アクセス トークンのバージョンは、 任意の組織ディレクトリ (任意の Azure AD ディレクトリ - マルチテナント) と個人用 Microsoft アカウント (Skype、Xbox など) のアカウントの種類以外を選択した場合に変更される可能性があります。 次の手順を使用して、アクセス トークンのバージョンが Office SSO の使用に適していることを確認します。
左側のウィンドウで、[マニフェスト] を選択 します。
Azure Active Directory アプリケーション マニフェストが表示されます。
requestedAccessTokenVersion
プロパティの値として「2」と入力します (api
オブジェクト内)。[保存] を選択します。
マニフェストが正常に更新されたことを示すメッセージがブラウザにポップアップ表示されます。
おめでとうございます! アプリの登録を完了して、Office アドインの SSO を有効にしました。
ソリューションを構成する
Begin フォルダーのルートで、Visual Studio でソリューション (.sln) ファイルを開きます。 ソリューション エクスプローラーの最上位ノード (プロジェクト ノードではなくソリューション ノード) を右クリック (または選択して長押し) し、[スタートアップ プロジェクトの設定] を選択します。
[共通プロパティ] で、[スタートアップ プロジェクト]、[マルチ スタートアップ プロジェクト] の順に選択します。 両方のプロジェクトの アクション が [開始] に設定されていること、および Office-Add-in-ASPNETCoreWebAPI プロジェクトが最初に一覧表示されていることを確認します。 ダイアログを閉じます。
ソリューション エクスプローラーで、Office-Add-in-ASPNET-SSO-manifest プロジェクトを選択し、アドイン マニフェスト ファイル "Office-Add-in-ASPNET-SSO.xml" を開き、ファイルの一番下までスクロールします。 タグの末尾のすぐ上
</VersionOverrides>
、次のマークアップがあります。<WebApplicationInfo> <Id>Enter_client_ID_here</Id> <Resource>api://localhost:44355/Enter_client_ID_here</Resource> <Scopes> <Scope>Files.Read</Scope> <Scope>profile</Scope> <Scope>openid</Scope> </Scopes> </WebApplicationInfo>
マークアップ内の両方の場所にあるプレースホルダー "Enter_client_ID_here" を、Office-Add-in-ASPNET-SSO アプリの登録時にコピーしたアプリケーション ID に置き換えます。 これは、appsettings.json ファイルのアプリケーション ID に使用した ID と同じです。
注:
<Resource> 値は、アドインを登録したときに設定したアプリケーション ID URI です。 <Scopes> セクションは、アドインが AppSource で販売されている場合にのみ同意ダイアログ ボックスを生成するために使用されます。
マニフェスト ファイルを保存して閉じます。
ソリューション エクスプローラーで、Office-Add-in-ASPNET-SSO-web プロジェクトを選択し、appsettings.json ファイルを開きます。
プレースホルダー Enter_client_id_hereを、前に保存したアプリケーション (クライアント) ID の値に置き換えます。
プレースホルダー Enter_client_secret_here を、前に保存したクライアント シークレットの値に置き換えます。
注:
また、シングルテナントのアプリ登録を構成した場合は、シングルテナントをサポートするように TenantId を変更する必要もあります。 Common 値を、シングルテナント サポートのアプリケーション (クライアント) ID に置き換えます。
appsettings.json ファイルを保存して閉じます。
クライアント側のコードの作成
アクセス トークンを取得し、アプリケーション サーバー REST API を呼び出す
Office-Add-in-ASPNETCore-WebAPI プロジェクトで、wwwroot\js\HomeES6.js ファイルを開きます。 これには、Trident (Internet エクスプローラー 11) Webview コントロールでも Promise が確実にサポートされるコードと、アドインの唯一のボタンにハンドラーを割り当てるための
Office.onReady
呼び出しが含まれています。注:
名前が示すように、HomeES6.js では javaScript ES6 構文が使用されます。
async
とawait
を使用すると、SSO API の基本的なシンプルさが最もよく示されるためです。 localhost サーバーが起動されると、このファイルは ES5 構文に変換され、サンプルで Trident がサポートされます。getUserFileNames
関数で、TODO 1
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。-
Office.auth.getAccessToken
を呼び出して、SSO を使用して Office からアクセス トークンを取得します。 このトークンには、ユーザーの ID とアプリケーション サーバーへのアクセス許可が含まれます。 - アクセス トークンは、アプリケーション サーバーへの実際の呼び出しを行う
callRESTApi
に渡されます。 その後、アプリケーション サーバーは OBO フローを使用して Microsoft Graph を呼び出します。 -
getAccessToken
の呼び出しからのエラーは、handleClientSideErrors
によって処理されます。
let fileNameList = null; try { let accessToken = await Office.auth.getAccessToken(options); fileNameList = await callRESTApi("/api/files", accessToken); } catch (exception) { if (exception.code) { handleClientSideErrors(exception); } else { showMessage("EXCEPTION: " + exception); } }
-
getUserFileNames
関数で、TODO 2
を次のコードに置き換えます。 これにより、ファイル名の一覧がドキュメントに書き込まれます。try { await writeFileNamesToOfficeDocument(fileNameList); showMessage("Your data has been added to the document."); } catch (error) { // The error from writeFileNamesToOfficeDocument will begin // "Unable to add filenames to document." showMessage(error); }
callRESTApi
関数で、TODO 3
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。- アクセス トークンを含む承認ヘッダーを構築します。 これにより、このクライアント コードが REST API へのアクセス許可を持っていることをアプリケーション サーバーに確認します。
- すべての戻り値が JSON で処理されるように、JSON の戻り値の型を要求します。
- エラーは処理のために
handleServerSideErrors
に渡されます。
try { let result = await $.ajax({ url: relativeUrl, headers: { "Authorization": "Bearer " + accessToken }, type: "GET", dataType: "json", contentType: "application/json; charset=utf-8" }); return result; } catch (error) { handleServerSideErrors(error); }
SSO エラーとアプリケーション REST API エラーを処理する
handleSSOErrors
関数で、TODO 4
を次のコードに置き換えます。 これらのエラーの詳細については、「Office アドインの SSO のトラブルシューティング (Troubleshoot SSO in Office Add-ins)」を参照してください。switch (error.code) { case 13001: // No one is signed into Office. If the add-in cannot be effectively used when no one // is logged into Office, then the first call of getAccessToken should pass the // `allowSignInPrompt: true` option. showMessage("No one is signed into Office. But you can use many of the add-ins functions anyway. If you want to log in, press the Get OneDrive File Names button again."); break; case 13002: // The user aborted the consent prompt. If the add-in cannot be effectively used when consent // has not been granted, then the first call of getAccessToken should pass the `allowConsentPrompt: true` option. showMessage("You can use many of the add-ins functions even though you have not granted consent. If you want to grant consent, press the Get OneDrive File Names button again."); break; case 13006: // Only seen in Office on the web. showMessage("Office on the web is experiencing a problem. Please sign out of Office, close the browser, and then start again."); break; case 13008: // Only seen in Office on the web. showMessage("Office is still working on the last operation. When it completes, try this operation again."); break; case 13010: // Only seen in Office on the web. showMessage("Follow the instructions to change your browser's zone configuration."); break; default: // For all other errors, including 13000, 13003, 13005, 13007, 13012, and 50001, fall back // to non-SSO sign-in by using MSAL authentication. showMessage("SSO failed. In these cases you should implement a falback to MSAL authentication."); break; }
handleServerSideErrors
関数で、TODO 5
を次のコードに置き換えます。// Check headers to see if admin has not consented. const header = errorResponse.getResponseHeader('WWW-Authenticate'); if (header !== null && header.includes('proposedAction=\"consent\"')) { showMessage("MSAL ERROR: " + "Admin consent required. Be sure admin consent is granted on all scopes in the Azure app registration."); return; }
handleServerSideErrors
関数で、TODO 6
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。- 場合によっては、2FA などの追加の同意が必要です。 Microsoft ID は、同意を完了するために必要な追加の要求を返します。 このコードでは、追加の要求と共に
authChallenge
プロパティを追加し、再度getUserfileNames
を呼び出します。 追加の要求でgetAccessToken
が再び呼び出されると、ユーザーは必要なすべての形式の認証を求めるプロンプトを受け取ります。
// Check if Microsoft Graph requires an additional form of authentication. Have the Office host // get a new token using the Claims string, which tells Microsoft identity to prompt the user for all // required forms of authentication. const errorDetails = JSON.parse(errorResponse.responseJSON.value.details); if (errorDetails) { if (errorDetails.error.message.includes("AADSTS50076")) { const claims = errorDetails.message.Claims; const claimsAsString = JSON.stringify(claims); getUserFileNames({ authChallenge: claimsAsString }); return; } }
- 場合によっては、2FA などの追加の同意が必要です。 Microsoft ID は、同意を完了するために必要な追加の要求を返します。 このコードでは、追加の要求と共に
handleServerSideErrors
関数で、TODO 7
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。- まれに、元の SSO トークンの有効期限が切れている場合、このエラー状態が検出され、
getUserFilenames
が再度呼び出されます。 これにより、更新されたアクセス トークンを返すgetAccessToken
への別の呼び出しが行われます。retryGetAccessToken
変数は再試行回数をカウントし、現在、再試行が 1 回だけ行われるよう構成されています。 - 最後に、エラーを処理できない場合、既定では作業ウィンドウにエラーが表示されます。
// Results from other errors (other than AADSTS50076) will have an ExceptionMessage property. const exceptionMessage = JSON.parse(errorResponse.responseText).ExceptionMessage; if (exceptionMessage) { // On rare occasions the access token is unexpired when Office validates it, // but expires by the time it is sent to Microsoft identity in the OBO flow. Microsoft identity will respond // with "The provided value for the 'assertion' is not valid. The assertion has expired." // Retry the call of getAccessToken (no more than once). This time Office will return a // new unexpired access token. if ((exceptionMessage.includes("AADSTS500133")) && (retryGetAccessToken <= 0)) { retryGetAccessToken++; getUserFileNames(); return; } else { showMessage("MSAL error from application server: " + JSON.stringify(exceptionMessage)); return; } } // Default error handling if previous checks didn't apply. showMessage(errorResponse.responseJSON.value);
- まれに、元の SSO トークンの有効期限が切れている場合、このエラー状態が検出され、
ファイルを保存します。
サーバー側のコードを作成する
サーバー側コードは、クライアントが呼び出す REST API を提供する ASP.NET Core サーバーです。 たとえば、REST API /api/files
は、ユーザーの OneDrive フォルダーからファイル名の一覧を取得します。 各 REST API 呼び出しでは、正しいクライアントがデータにアクセスしていることを確認するために、クライアントによるアクセス トークンが必要です。 アクセス トークンは、On-Behalf-Of フロー (OBO) を介して Microsoft Graph トークンと交換されます。 新しい Microsoft Graph トークンは、後続の API 呼び出しのために MSAL.NET ライブラリによってキャッシュされます。 サーバー側コードの外部に送信されることはありません。 Microsoft ID ドキュメントは、クライアント側のコードから Microsoft サービスへのフローの途中にあるため、このサーバーを中間層サーバーと呼びます。 詳細については、「中間層のアクセス トークン要求」を参照してください。
Microsoft Graph と OBO フローを構成する
Program.cs
ファイルを開き、TODO 8
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。- REST API に必要なトークン検証を処理するために必要なサービスが追加されます。
-
EnableTokenAcquisitionToCallDownstreamApi().AddMicrosoftGraph(...)
の呼び出しに Microsoft Graph と OBO フローのサポートが追加されます。 OBO フローは自動的に処理され、Microsoft Graph SDK は REST API コントローラーに提供されます。 - DownstreamApi 構成は、appsettings.json ファイルで指定します。
// Add services to the container. builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration) .EnableTokenAcquisitionToCallDownstreamApi() .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches();
/api/filenames REST API を作成する
Controllers フォルダーで、FilesController.cs ファイルを開きます。
TODO 9
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。-
[Authorize]
属性を指定して、FilesController
クラス内のすべての REST API の呼び出しごとにアクセス トークンが検証されるようにします。 詳細については、「 トークンの検証」を参照してください。 - クライアントがアクセス トークンに正しいaccess_as_userスコープを持っていることを確認するために、
[RequiredScope("access_as_user")]
属性を指定します。 - コンストラクターは、Microsoft Graph REST API の呼び出しを容易にするために、
_graphServiceClient
オブジェクトを初期化します。
[Authorize] [Route("api/[controller]")] [RequiredScope("access_as_user")] public class FilesController : Controller { public FilesController(ITokenAcquisition tokenAcquisition, GraphServiceClient graphServiceClient, IOptions<MicrosoftGraphOptions> graphOptions) { _tokenAcquisition = tokenAcquisition; _graphServiceClient = graphServiceClient; _graphOptions = graphOptions; } private readonly ITokenAcquisition _tokenAcquisition; private readonly GraphServiceClient _graphServiceClient; private readonly IOptions<MicrosoftGraphOptions> _graphOptions; // TODO 10: Add the REST API to get filenames. }
-
TODO 10
を次のコードに置き換えます。 このコードについては、以下の点に注意してください。-
/api/files
REST API が作成されます。 - クラスを介して MSAL からの例外を処理します。
-
ServiceException
クラスを介した Microsoft Graph API 呼び出しからの例外を処理します。
// GET api/files [HttpGet] [Produces("application/json")] public async Task<IActionResult> Get() { List<DriveItem> result = new List<DriveItem>(); try { var files = await _graphServiceClient.Me.Drive.Root.Children.Request() .Top(10) .Select(m => new { m.Name }) .GetAsync(); result = files.ToList(); } catch (MsalException ex) { var errorResponse = new { message = "An authentication error occurred while acquiring a token for downstream API", details = ex.Message }; return StatusCode((int)HttpStatusCode.Unauthorized, Json(errorResponse)); } catch (ServiceException ex) { if (ex.InnerException is MicrosoftIdentityWebChallengeUserException challengeException) { _tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeader(_graphOptions.Value.Scopes.Split(' '), challengeException.MsalUiRequiredException); } else { var errorResponse = new { message = "An error occurred calling Microsoft Graph", details = ex.RawResponseBody }; return StatusCode((int)HttpStatusCode.BadRequest, Json(errorResponse)); } } catch (Exception ex) { var errorResponse = new { message = "An error occurred while calling the downstream API", details = ex.Message }; return StatusCode((int)HttpStatusCode.BadRequest, Json(errorResponse)); } return Json(result); }
-
ソリューションを実行する
Visual Studio の [ビルド ] メニューの [ ソリューションのクリーン] を選択します。 終了したら、[ビルド] メニューをもう一度開き、[ソリューションのビルド] を選択します。
ソリューション エクスプローラーで、Office-Add-in-ASPNET-SSO-manifest プロジェクト ノードを選択します。
[プロパティ] ウィンドウで、[ドキュメントの開始] ドロップダウンを開き、3 つのオプション (Excel、Word、または PowerPoint) のいずれかを選択します。
F5 キーを押します。 または、[ デバッグ] > [デバッグの開始] を選択します。
Office アプリケーションで、SSO ASP.NET グループで [アドインの表示] を選択して、作業ウィンドウ アドインを開きます。
[ Get OneDrive File Names]\(OneDrive ファイル名の取得\) を選択します。 Microsoft 365 Educationまたは職場アカウント、または Microsoft アカウントを使用して Office にログインしていて、SSO が期待どおりに機能している場合は、作業ウィンドウにOneDrive for Businessの最初の 10 個のファイルとフォルダー名が表示されます。 ログインしていない場合、または SSO をサポートしていないシナリオ、または何らかの理由で SSO が機能しない場合は、サインインするように求められます。 サインインすると、ファイル名とフォルダー名が表示されます。
アドインを展開する
ステージング サーバーまたは運用サーバーにデプロイする準備ができたら、プロジェクト ソリューションの次の領域を必ず更新してください。
- appsettings.json ファイルで、ドメインをステージング ドメインまたは運用ドメイン名に変更します。
- ステージング URL または運用 URL を使用するように、プロジェクト全体で
localhost:7080
への参照を更新します。 - Azure アプリ登録の
localhost:7080
への参照を更新するか、ステージングまたは運用環境で使用するための新しい登録を作成します。
詳細については、「ASP.NET Coreのホストとデプロイ」を参照してください。
関連項目
Office Add-ins