次の方法で共有


シングル サインオンを使用する 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) を使用したフォールバック認証の両方がサポートされます。

  1. Microsoft 365 テナントへの管理者資格情報を使用して Azure portal にサインインします。 たとえば、「 MyName@contoso.onmicrosoft.com 」のように入力します。

  2. [アプリの登録] を選択します。 アイコンが表示されない場合は、検索バーで "アプリの登録" を検索します。

    Azure portal のホーム ページ。

    [アプリの登録] ページが表示されます。

  3. [新規登録] を選択します。

    [アプリの登録] ウィンドウでの新しい登録。

    [アプリケーション登録] ページが表示されます。

  4. [アプリケーションを登録] ページで、次のように値を設定します。

    • <add-in-name>[名前] を設定します。
    • [サポートされているアカウントの種類] を[任意の組織のディレクトリ (任意の Azure AD ディレクトリ - マルチテナント)] と個人用 Microsoft アカウント (Skype、Xbox など) に設定します。
    • [ リダイレクト URI] を 設定して、プラットフォーム の単一ページ アプリケーション (SPA) を使用し、URI を https://<fully-qualified-domain-name>/dialog.htmlします。

    名前とサポートされているアカウントが完了したアプリケーション ウィンドウを登録します。

  5. [登録] を選択します。 アプリケーション登録が作成されたことを示すメッセージが表示されます。

    アプリケーションの登録が作成されたことを示すメッセージ。

  6. アプリケーション (クライアント) ID とディレクトリ (テナント) ID の値をコピーして保存します。 以降の手順では、それらの両方を使用します。

    クライアント ID とディレクトリ ID を表示する Contoso のアプリ登録ウィンドウ。

クライアント シークレットを追加する

アプリケーション パスワードと呼ばれることもあります。クライアント シークレットは、証明書の代わりにアプリが ID 自体に使用できる文字列値です。

  1. 左側のウィンドウで、[ 証明書 & シークレット] を選択します。 次に、[ クライアント シークレット ] タブで、[ 新しいクライアント シークレット] を選択します。

    [証明書 & シークレット] ウィンドウ。

    [ クライアント シークレットの追加] ウィンドウが表示されます。

  2. クライアント シークレットの説明を追加します。

  3. シークレットの有効期限を選択するか、カスタム有効期間を指定します。

    • クライアント シークレットの有効期間は、2 年間 (24 か月) 以下に制限されます。 24 か月を超えるカスタム有効期間を指定することはできません。
    • Microsoft では、有効期限の値を 12 か月未満に設定することをお勧めします。

    説明と有効期限が完了したクライアント シークレット ウィンドウを追加します。

  4. [追加] を選択します。 新しいシークレットが作成され、値が一時的に表示されます。

重要

クライアント アプリケーション コードで使用するシークレットの値を記録します。 このウィンドウを離れた後、このシークレット値は 再び表示されることはありません

Web API を公開する

  1. 左側のウィンドウで、[ API の公開] を選択します。

    [ API の公開 ] ウィンドウが表示されます。

    アプリ登録の [API の公開] ウィンドウ。

  2. [ 設定] を選択して、アプリケーション ID URI を生成します。

    アプリ登録の [API の公開] ウィンドウの [設定] ボタン。

    アプリケーション ID URI を設定するためのセクションは、生成されたアプリケーション ID URI を api://<app-id>フォームに表示します。

  3. アプリケーション ID URI を api://<fully-qualified-domain-name>/<app-id>に更新します。

    localhost ポートが 44355 に設定されている [アプリ ID URI] ペインを編集します。

    • アプリケーション 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. のプロセスを繰り返します)。

スコープを追加する

  1. [ API の公開 ] ページで、[ スコープの追加] を選択します。

    [スコープの追加] ボタンを選択します。

    [ スコープの追加] ウィンドウが開きます。

  2. [ スコープの追加] ウィンドウで、スコープ の属性を指定します。 次の表は、 profileopenidFiles.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.
  3. [状態] を [有効] に設定し、[スコープの追加] を選択します。

    [状態] を [有効] に設定し、[スコープの追加] ボタンを選択します。

    定義した新しいスコープがウィンドウに表示されます。

    [API の公開] ウィンドウに表示される新しいスコープ。

    注:

    テキスト フィールドのすぐ下に表示される [スコープ名] のドメイン部分は、たとえば api://localhost:6789/c6c1f32b-5e55-4997-881a-753cc1d563b7/access_as_user のように手順で設定された [アプリケーション ID URI] と自動的に一致し、最後に /access_as_user が追加されます。

  4. [クライアント アプリケーションの追加] を選択します。

    [クライアント アプリケーションの追加] を選択します。

    [ クライアント アプリケーションの追加] ウィンドウが表示されます。

  5. [ クライアント 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)
  6. [ 承認されたスコープ] で、[ api://<fully-qualified-domain-name>/<app-id>/access_as_user ] チェック ボックスをオンにします。

  7. [アプリケーションの追加] を選択します。

    [クライアント アプリケーションの追加] ウィンドウ。

Microsoft Graph のアクセス許可を追加する

  1. 左側のウィンドウで、[ API アクセス許可] を選択します。

    [API アクセス許可] ウィンドウ。

    [API アクセス許可] ウィンドウが開きます。

  2. [アクセス許可を追加] を選択します。

    [API アクセス許可] ウィンドウにアクセス許可を追加する。

    [ API のアクセス許可の要求 ] ウィンドウが開きます。

  3. [Microsoft Graph] を選択します。

    [Api のアクセス許可の要求] ウィンドウと [Microsoft Graph] ボタン。

  4. [委任されたアクセス許可] を選択します。

    委任されたアクセス許可を持つ [API のアクセス許可の要求] ウィンドウボタン。

  5. [ アクセス許可の選択 ] 検索ボックスで、アドインで必要なアクセス許可を検索します。 たとえば、Outlook アドインの場合は、 profileopenidFiles.ReadWriteMail.Readを使用できます。

    注:

    User.Read アクセス許可は既定でリストされています。 必要なアクセス許可のみを要求することをお勧めします。アドインで実際に必要ない場合は、このアクセス許可のチェック ボックスをオフにすることをお勧めします。

  6. 表示される各アクセス許可のチェック ボックスをオンにします。 アクセス許可は、各アクセス許可を選択しても一覧に表示されません。 アドインに必要なアクセス許可を選択したら、[ アクセス許可の追加] を選択します。

    一部のアクセス許可が選択されている [API のアクセス許可の要求] ウィンドウ。

  7. [ テナント名] の [管理者の同意の付与] を選択します。 表示される確認のために [ はい ] を選択します。

アクセス トークンのバージョンを構成する

アプリで許容されるアクセス トークンのバージョンを定義する必要があります。 この構成は、Azure Active Directory アプリケーション マニフェストで行われます。

アクセス トークンのバージョンを定義する

アクセス トークンのバージョンは、 任意の組織ディレクトリ (任意の Azure AD ディレクトリ - マルチテナント) と個人用 Microsoft アカウント (Skype、Xbox など) のアカウントの種類以外を選択した場合に変更される可能性があります。 次の手順を使用して、アクセス トークンのバージョンが Office SSO の使用に適していることを確認します。

  1. 左側のウィンドウで、[マニフェスト] を選択 します

    [Azure マニフェスト] を選択します。

    Azure Active Directory アプリケーション マニフェストが表示されます。

  2. accessTokenAcceptedVersion プロパティの値として 2 を入力します。

    受け入れられたアクセス トークンのバージョンの値。

  3. [保存] を選択します。

    マニフェストが正常に更新されたことを示すメッセージがブラウザにポップアップ表示されます。

    マニフェストが更新されたメッセージ。

おめでとうございます! アプリの登録を完了して、Office アドインの SSO を有効にしました。

ソリューションを構成する

  1. Begin フォルダーのルートで、Visual Studio でソリューション (.sln) ファイルを開きます。 ソリューション エクスプローラーの最上位ノード (プロジェクト ノードではなくソリューション ノード) を右クリック (または長押し) し、[スタートアップ プロジェクトの設定] を選択します。

  2. [共通プロパティ] で、[スタートアップ プロジェクト]、[マルチ スタートアップ プロジェクト] の順に選択します。 両方のプロジェクトの アクション[開始] に設定されていること、および Office-Add-in-ASPNETCoreWebAPI プロジェクトが最初に一覧表示されていることを確認します。 ダイアログを閉じます。

  3. ソリューション エクスプローラーで、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>
    
  4. マークアップ内の両方の場所にあるプレースホルダー "Enter_client_ID_here" を、Office-Add-in-ASPNET-SSO アプリの登録時にコピーしたアプリケーション ID に置き換えます。 これは、appsettings.json ファイルのアプリケーション ID に使用した ID と同じです。

    注:

    <Resource> 値は、アドインを登録したときに設定したアプリケーション ID URI です。 <Scopes> セクションは、アドインが AppSource で販売されている場合にのみ同意ダイアログ ボックスを生成するために使用されます。

  5. マニフェスト ファイルを保存して閉じます。

  6. ソリューション エクスプローラーで、Office-Add-in-ASPNET-SSO-web プロジェクトを選択し、appsettings.json ファイルを開きます。

  7. プレースホルダー Enter_client_id_hereを、前に保存したアプリケーション (クライアント) ID の値に置き換えます。

  8. プレースホルダー Enter_client_secret_here を、前に保存したクライアント シークレットの値に置き換えます。

    注:

    また、シングルテナントのアプリ登録を構成した場合は、シングルテナントをサポートするように TenantId を変更する必要もあります。 Common 値を、シングルテナント サポートのアプリケーション (クライアント) ID に置き換えます。

  9. appsettings.json ファイルを保存して閉じます。

クライアント側のコードの作成

アクセス トークンを取得し、アプリケーション サーバー REST API を呼び出す

  1. Office-Add-in-ASPNETCore-WebAPI プロジェクトでwwwroot\js\HomeES6.js ファイルを開きます。 これには既に、Trident (Internet Explorer 11) Webview コントロールでも Promise がサポートされていることを保証するコードと、アドインの唯一のボタンにハンドラーを割り当てる Office.onReady 呼び出しがあります。

    注:

    名前が示すように、HomeES6.js では javaScript ES6 構文が使用されます。 asyncawait を使用すると、SSO API の基本的なシンプルさが最もよく示されるためです。 localhost サーバーが起動されると、このファイルは ES5 構文に変換され、サンプルで Trident がサポートされます。

  2. 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);
        }
    }
    
    
  3. 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);
     }
    
  4. 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 エラーを処理する

  1. 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;
     }
    
  2. 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;
    }
    
    
  3. 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;
        }
    }
    
  4. 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);
    
  5. ファイルを保存します。

サーバー側のコードを作成する

サーバー側コードは、クライアントが呼び出す 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 フローを構成する

  1. 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 を作成する

  1. 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.
    
    }
    
  2. 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);
        }
    

ソリューションを実行する

  1. Visual Studio の [ビルド ] メニューの [ ソリューションのクリーン] を選択します。 終了したら、[ビルド] メニューをもう一度開き、[ソリューションのビルド] を選択します。

  2. ソリューション エクスプローラーでOffice-Add-in-ASPNET-SSO-manifest プロジェクト ノードを選択します。

  3. [プロパティ] ウィンドウで、[ドキュメントの開始] ドロップダウンを開き、3 つのオプション (Excel、Word、または PowerPoint) のいずれかを選択します。

    目的の Office クライアント アプリケーション (Excel、PowerPoint、Word) を選択します。

  4. F5 キーを押します。 または、[ デバッグ] > [デバッグの開始] を選択します。

  5. Office アプリケーションで、SSO ASP.NET グループで [アドインの表示] を選択して、作業ウィンドウ アドインを開きます。

  6. [ 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 のホストとデプロイ」を参照してください。

関連項目