次の方法で共有


シングル サインオンを使用する 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 など) に設定します。
    • プラットフォームシングルページ アプリケーション (SPA)URI を 使用するようにリダイレクト 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 を設定するためのセクションは、 形式 api://<app-id>で生成されたアプリケーション ID URI と共に表示されます。

  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>
    • <app-id> (fully-qualified-domain-nameGUID) の間api://に を挿入します。 たとえば、「 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. [ スコープの追加] ウィンドウで、スコープ の属性を指定します。 次の表は、および のアクセス許可を必要とするおよび Outlook アドインの値のprofileopenidFiles.ReadWrite例をMail.Read示しています。 アドインに必要なアクセス許可に合わせてテキストを変更します。

    フィールド 説明
    スコープ名 スコープの名前。 一般的なスコープの名前付け規則は です 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 を事前に承認する場合は、(Microsoft Teams デスクトップと Teams モバイル) と 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 (Teams on the web) を追加1fec8e78-bce4-4aaf-ab1b-5451cc387264します。

    注:

    ID は ea5a67f6-b6f3-4338-b240-c655ddc3cc8e 、次のすべてのプラットフォームで 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 アドインの場合、および Mail.Readを使用Files.ReadWriteprofileopenidできます。

    注:

    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 と同じです。

    注:

    [<リソース]> の値は、アドインを登録したときに設定したアプリケーション ID URI です。 [<スコープ]> セクションは、アドインが 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 エクスプローラー 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] のすべての REST API の呼び出しごとにアクセス トークンが検証されるように属性を FilesController 指定します。 詳細については、「 トークンの検証」を参照してください。
    • クライアントがアクセス トークンに [RequiredScope("access_as_user")] 正しい access_as_user スコープを持っていることを確認する属性を指定します。
    • コンストラクターは、 _graphServiceClient Microsoft Graph REST API の呼び出しを容易にするために オブジェクトを初期化します。
    [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 を次のコードに置き換えます。 このコードについては、以下の点に注意してください。

    • REST API が作成されます /api/files
    • クラスを介して MSAL からの例外を MsalException 処理します。
    • クラスを介した Microsoft Graph API 呼び出しからの例外をServiceException処理します。
     // 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のホストとデプロイ」を参照してください。

関連項目