SharePoint Framework での、Azure AD でセキュリティ保護されたマルチテナント エンタープライズ API の使用

この記事では、SharePoint Framework ソリューションから Azure Active Directory でセキュリティ保護されたマルチテナント エンタープライズ API に接続する方法を説明します。 API を作成してセキュリティで保護する方法と、SharePoint Framework ソリューションを構築する方法の両方について取り上げます。

Azure AD でセキュリティ保護されたマルチテナント エンタープライズ API の作成

まず、Azure Active Directory でセキュリティ保護されたマルチテナント エンタープライズ API を作成します。 SharePoint Frameworkの観点から API を実装する方法に制限はありませんが、このチュートリアルでは、Azure Functionsを使用して API を構築し、Azure App Service認証を使用してセキュリティで保護します。

組織のアプリケーションを公開する特定の API は、おそらく既に存在するはずですが、このセクションでは、実装および構成手順全体の概要を説明します。

Azure 関数を作成する

Azure portalで、新しい関数アプリを作成します。

Azure で関数アプリを作成する方法の詳細については、サポート記事「Azure Portal から関数アプリを作成する」を参照してください。

Function App で、HTTP でトリガーされる新しい関数を作成します。 この例では、C# を使用してビルドしますが、使用できるプログラミング言語に関する制限はありません。

関数アプリで、[ 追加 ] ボタンを選択し、使用可能な関数の種類の一覧から [ HTTP トリガー] を選択します。

Azure portalで強調表示されている [HTTP トリガー] リンク

関数の設定で、関数名を指定し、[ 承認レベル][匿名] に設定します。

Azure portal での新しい Azure 関数の設定

Azure 関数をセキュリティで保護する方法は、いくつかあります。 Azure AD を使用して関数をセキュリティで保護する必要があるため、関数自体ではなく、基になる関数アプリをセキュリティで保護します。 そのため、この段階では関数自体のセキュリティ保護は行わないように設定します。 関数アプリに適用される認証設定は、このアプリに含まれるすべての関数に適用されます。

設定を確認して関数を作成するには、[関数の 作成 ] ボタンを選択します。

関数を作成したら、その内容を次のスニペットに置き換えます。

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    return req.CreateResponse(HttpStatusCode.OK, new List<object> {
        new {
            Id = 1,
            OrderDate = new DateTime(2016, 1, 6),
            Region = "east",
            Rep = "Jones",
            Item = "Pencil",
            Units = 95,
            UnitCost = 1.99,
            Total = 189.05
        },
        new {
            Id = 2,
            OrderDate = new DateTime(2016, 1, 23),
            Region = "central",
            Rep = "Kivell",
            Item = "Binder",
            Units = 50,
            UnitCost = 19.99,
            Total = 999.50
        },
        new {
            Id = 3,
            OrderDate = new DateTime(2016, 2, 9),
            Region = "central",
            Rep = "Jardine",
            Item = "Pencil",
            Units = 36,
            UnitCost = 4.99,
            Total = 179.64
        },
        new {
            Id = 4,
            OrderDate = new DateTime(2016, 2, 26),
            Region = "central",
            Rep = "Gill",
            Item = "Pen",
            Units = 27,
            UnitCost = 19.99,
            Total = 539.73
        },
        new {
            Id = 5,
            OrderDate = new DateTime(2016, 3, 15),
            Region = "west",
            Rep = "Sorvino",
            Item = "Pencil",
            Units = 56,
            UnitCost = 2.99,
            Total = 167.44
        }
    });
}

[テストと実行] ボタンを選択し、[実行] をクリックして、関数が正しく動作していることを確認します。

Azure portalで強調表示されている [テストと実行] ボタン

関数が正常に実行された場合、テスト ウィンドウに [ステータス: 200 OK] ラベルとリストの順序が表示されます。

Azure portalで強調表示されている [OK] ボタン

セキュリティで保護された Azure 関数

Azure 関数が機能したので、次の手順では、Azure Active Directory でセキュリティで保護し、アクセスするには組織のアカウントでサインインする必要があります。

[関数アプリ] ブレードのサイド パネルで、[ 認証/承認 ] リンクを選択します。

Azure portal の関数アプリ ブレードで強調表示された [認証/承認] リンク

[認証/承認] ブレードで、[App Service 認証] トグル ボタンを [オン] にして、App Service 認証を有効にします。

[ 要求が認証されていないときに実行するアクション ] ドロップダウンで、値を [ Azure Active Directory でログイン] に変更します。

この設定により、API への匿名要求が許可されないようにします。

次に、認証プロバイダーのリストから [Azure Active Directory] を選択します。

関数アプリの認証プロバイダーの一覧で強調表示された [Azure Active Directory]

[Azure Active Directory の設定] ブレードで、最初の [管理モード] オプションとして [簡易] を選択します。 2 番目の [管理モード] オプションには、[新しい AD アプリを作成する] を選択します。

Azure portal の関数アプリで開いた [Azure Active Directory の設定] ブレード

[OK] ボタンを選択して選択内容を確認します。

重要

続行する前に、[アプリの作成] フィールドの値をメモします。 この値は、API のセキュリティ保護に使用する Azure AD アプリケーションの名前を表し、後でSharePoint Framework プロジェクトから API にアクセスするためのアクセス許可を要求するために必要になります。

Function App の認証と承認の設定を更新するために、[保存] ボタンを選択します。

Azure portal の関数アプリの [認証/承認] ブレードで強調表示された [保存] ボタン

API が適切にセキュリティ保護されていることを確認するには、新しいブラウザー ウィンドウをプライベート モードで開いて API に移動します。 認証設定が正しく適用されている場合は、Azure AD のログイン ページにリダイレクトされます。

Azure AD のログイン ページ

Azure AD アプリケーションをマルチテナントに変更する

既定では、Azure AD アプリケーションを使用して Azure 関数をセキュリティ保護すると、その Azure 関数を使用できるのは、そのアプリケーションが配置されている Azure AD に属するユーザーに制限されます。 別のテナントでも API を使用できるようにするには、Azure AD アプリケーションをマルチテナントに変更する必要があります。

アプリケーションをマルチテナントに変更する

Azure portalのホーム ページに移動し、Azure Active Directory を検索します

Azure AD

左側のブレードで、[アプリの登録] を選択し、関数アプリの作成時に自動的に作成されたアプリを選択します。

Azure portalで強調表示されている [アプリの登録] ボタン

[ API を公開 する] で、[ アプリ ID URI ] フィールドを更新し、Azure AD アプリの ID を変更して、 で始まる https://yourtenant.onmicrosoft.comようにします。例: https://contoso.onmicrosoft.com/contoso-api。 この変更は、Azure AD アプリが他のテナントで使用され、すべての Azure Active Directory でアプリの一意性を確保するために必要です。

Azure portalのアプリ ID URI

[ 概要 ] で、[ サポートされているアカウントの種類 ] リンクをクリックします。これは [組織のみ] になります。 アプリをマルチテナント化するように変更する必要があります。

Azure portalで強調表示されている [サポートされているアカウントの種類] ボタン

[マルチテナント] フィールドの値を [はい] に切り替えます。

認証で強調表示されている [保存] ボタン

最後に、変更内容を確認するために、ツールバーから [保存] を選択します。

他の Azure AD のユーザーにアプリケーションの使用を許可する

Azure AD の簡易設定を使用して API をセキュリティ保護したため、この API を使用できるのは、アプリケーションが配置されている Azure AD に属するユーザーだけに制限されます。 他のテナントのユーザーも API を使用できるようにするためには、セキュリティ設定を調整する必要があります。

関数アプリの [認証/承認 ] ブレードに戻るまで、開いているすべてのブレードを閉じます。 認証プロバイダーのリストから、[Azure Active Directory] を選択します。

関数アプリの認証プロバイダーの一覧で強調表示された [Azure Active Directory]

[Azure Active Directory の設定] ブレードで、[管理モード] オプションの値を [拡張] に切り替えます。

Function App の [Azure Active Directory の設定] で強調表示された、[管理モード] の [拡張] 値

次に、[発行元の URL] フィールドの値をクリアします。 これにより、他の Azure Active Directory に属するユーザーが API に対して認証できるようになります。

変更内容を確認する前に、[クライアント ID] フィールドの値をコピーします。 API のアクセス トークンを要求するには、Web パーツを構築するときに必要になります。

[OK] ボタンを使用して変更を確認し、[保存] ボタンを使用して変更を確認します。

CORS を有効にする

Function App は、SharePoint ページで実行されている JavaScript から呼び出されます。 この API は SharePoint Portal とは異なるドメインでホストされているため、API 呼び出しには、クロスドメイン セキュリティの制約事項が適用されます。 既定では、Azure Function Apps を使用して実装された API は、他のドメインから呼び出すことはできません。 他のドメインから呼び出せるようにするには、Function App の CORS 設定を調整します。

関数アプリで、 CORS リンクをクリックします。

関数アプリの [プラットフォーム機能] タブで強調表示された [CORS] リンク

許可される配信元の一覧に、SharePoint テナントの URL (例: https://contoso.sharepoint.com) を追加します。

関数アプリの CORS 設定で許可されたオリジンの一覧に追加された SharePoint テナントの URL

[保存] ボタンを使用して変更内容を確認します。

テナント内のユーザーが別のテナントの API を使用できるようにするには、その API を承認する必要があります。 承認 (同意とも呼ばれる) は、ユーザーと管理者 (組織) の 2 つのレベルで行うことができます。 このシナリオでは、管理者の同意を使用して、組織全体で使用する API を承認します。

注:

通常は、API を公開するサイトで、テナントで API に同意するためのプロセスが行われます。 この例では、プロセスのしくみを理解するために必要な手順を手動で実行します。

Function App ブレードで、対象の関数を選択します。

関数の URL を取得するために、ツールバーから [関数の URL の取得] オプションを選択します。

Function App ブレードのツールバーで強調表示された [関数の URL の取得] オプション

[関数の URL の取得] ダイアログで、[コピー] ボタンを使用して関数の URL をコピーします。

[関数の URL の取得] ダイアログで強調表示された [コピー] ボタン

新しいブラウザー ウィンドウで、コピーした関数 URL に移動します。 サインインするよう求められたら、API を使用できるようにする Office 365 テナントの管理者アカウントを使用してサインインします。

サインインすると、この API の使用に同意するように求められます。

エンタープライズ API の使用に同意するよう求めるダイアログ

ただし、これはユーザーの同意です。 管理者の同意に切り替え、組織全体で使用する API を承認するには、URL &prompt=admin_consent に追加します。 もう一度、同意ダイアログが表示されますが、今回は、アプリが組織内のすべてのユーザーに対して指定されたリソースにアクセスでき、他のユーザーにはプロンプトが表示されないというメッセージが表示されます。

[承諾] ボタンを選択して、組織内のユーザーが API を使用することを確認します。

SharePoint Framework から、Azure AD でセキュリティ保護された API を使用する

API が構成されて機能するようになったら、次のステップは、この API を使用する SharePoint Framework ソリューションを作成することです。

続行する前に、バージョン 1.4.1 以上の SharePoint Framework Yeoman ジェネレーターがインストールされていることを確認してください。 ジェネレーターをグローバルにインストールした場合は、コマンド ラインで npm ls -g --depth=0 を実行して、インストールされているバージョンを確認できます。

新しい SharePoint Framework プロジェクトを作成する

まずは、新しい SharePoint Framework プロジェクトを作成します。 コマンド ラインで次のコマンドを実行して、プロジェクトの新しいフォルダーを作成します。

md contoso-api

コマンド ラインで次のコマンドを実行して、作業ディレクトリを変更します。

cd contoso-api

新しいプロジェクトを作成するには、次のように SharePoint Framework Yeoman ジェネレーターを実行します。

yo @microsoft/sharepoint

ダイアログが表示されたら、次の値を使用します。

  • ソリューション名: contoso api
  • ベースライン パッケージ: SharePoint Online のみ (最新)
  • ファイルの配置場所: 現在のフォルダーを使用する
  • テナント全体で展開を有効化するかどうか: Y
  • 作成するコンポーネントの種類: Web パーツ
  • 作成する Web パーツの名前: Orders
  • Web パーツの説明: 最近の注文を表示
  • 使用するフレームワーク: JavaScript フレームワークは使用しない

ターミナル ウィンドウでの SharePoint Framework Yeoman ジェネレーターのダイアログ

プロジェクトが作成されたら、コード エディターでプロジェクトを開きます。 このチュートリアルでは、Visual Studio Code を使用します。

Visual Studio Code で開かれた SharePoint Framework プロジェクト

エンタープライズ API へのアクセス許可を要求する

既定では、SharePoint Frameworkは、Office 365と同じ Azure Active Directory に登録されていても、エンタープライズ API にアクセスできなくなります。 これは意図的な設定であり、SharePoint に展開されたスクリプトやクライアント側のソリューションに公開する API を、組織が意識的に選択できるようにすることを目的としています。 エンタープライズ API にアクセスできるようにするには、作成中の SharePoint Framework プロジェクトからアクセス許可要求を発行する必要があります。

コード エディターで、config/package-solution.json ファイルを開きます。

Visual Studio Code で開かれたパッケージ ソリューション ファイル

[solution] プロパティに、webApiPermissionRequests という名前の新しいセクションを追加し、API をセキュリティ保護するために使用している Azure AD アプリケーションへの参照を設定します。

{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
  "solution": {
    "name": "contoso-api-client-side-solution",
    "id": "8cbc01fb-bab6-48fc-afec-2c2053759771",
    "version": "1.0.0.0",
    "includeClientSideAssets": true,
    "skipFeatureDeployment": true,
    "webApiPermissionRequests": [
      {
        "resource": "contoso-api",
        "scope": "user_impersonation"
      }
    ]
  },
  "paths": {
    "zippedPackage": "solution/contoso-api.sppkg"
  }
}

resource プロパティの値は、API のセキュリティ保護に使用される Azure AD アプリケーションの名前のみを参照します。 scope プロパティの値は、ソリューションが API と通信するために必要なアクセス許可スコープを指定します。 このチュートリアルでは、API を保護する目的でのみ Azure AD を使用するため、適用範囲として user_impersonation を使用します。

注:

作成済みのエンタープライズ API に接続する必要がある場合は、管理者に連絡して、その API をセキュリティ保護するために使用している Azure AD アプリケーションの詳細を入手してください。 アプリケーション ID、アプリケーションが公開するアクセス許可、構成されている対象ユーザーなどの情報が必要です。

エンタープライズ API に接続する

最後に残された作業は、エンタープライズ API への実際の接続を実装することです。

コード エディターで、src\webparts\orders\OrdersWebPart.ts ファイルを開きます。

Visual Studio Code で開かれた OrdersWebPart.ts ファイル

ファイルの最上部のセクションに次のコード スニペットを追加して、AadHttpClient クラスと HttpClientResponse クラスを参照します。

import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http';

OrdersWebPart クラスに、ordersClient という名前の新しいクラス変数を追加します。

export default class OrdersWebPart extends BaseClientSideWebPart<IOrdersWebPartProps> {
  private ordersClient: AadHttpClient;

  // shortened for brevity
}

次に、AadHttpClient のインスタンスを作成するために、OrdersWebPart クラスに含まれる onInit メソッドを次のように上書きします。

export default class OrdersWebPart extends BaseClientSideWebPart<IOrdersWebPartProps> {
  private ordersClient: AadHttpClient;

  protected onInit(): Promise<void> {
    return new Promise<void>((resolve: () => void, reject: (error: any) => void): void => {
      this.context.aadHttpClientFactory
        .getClient('https://contoso-api.azurewebsites.net')
        .then((client: AadHttpClient): void => {
          this.ordersClient = client;
          resolve();
        }, err => reject(err));
    });
  }

  // shortened for brevity
}

メソッドに getClient() 渡される URI は、エンタープライズ API のセキュリティ保護に使用される Azure AD アプリケーションのアプリケーション ID URI です。

最後に、エンタープライズ API から取得した注文を読み込んで表示するように render メソッドを拡張します。

export default class OrdersWebPart extends BaseClientSideWebPart<IOrdersWebPartProps> {
  private ordersClient: AadHttpClient;

  protected onInit(): Promise<void> {
    return new Promise<void>((resolve: () => void, reject: (error: any) => void): void => {
      this.context.aadHttpClientFactory
        .getClient('https://contoso-api.azurewebsites.net')
        .then((client: AadHttpClient): void => {
          this.ordersClient = client;
          resolve();
        }, err => reject(err));
    });
  }

  public render(): void {
    this.context.statusRenderer.displayLoadingIndicator(this.domElement, 'orders');

    this.ordersClient
      .get('https://contoso-api.azurewebsites.net/api/Orders', AadHttpClient.configurations.v1)
      .then((res: HttpClientResponse): Promise<any> => {
        return res.json();
      })
      .then((orders: any): void => {
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.domElement.innerHTML = `
          <div class="${ styles.orders}">
            <div class="${ styles.container}">
              <div class="${ styles.row}">
                <div class="${ styles.column}">
                  <span class="${ styles.title}">Orders</span>
                  <p class="${ styles.description}">
                    <ul>
                      ${orders.map(o => `<li>${o.Rep} $${o.Total}</li>`).join('')}
                    </ul>
                  </p>
                  <a href="https://aka.ms/spfx" class="${ styles.button}">
                    <span class="${ styles.label}">Learn more</span>
                  </a>
                </div>
              </div>
            </div>
          </div>`;
      }, (err: any): void => {
        this.context.statusRenderer.renderError(this.domElement, err);
      });
  }

  // shortened for brevity
}

ソリューションを SharePoint アプリ カタログにデプロイする

SharePoint Framework ソリューションの実装が完了したら、次のステップは、このソリューションを SharePoint に展開することです。

まず、コマンド ラインで を実行して、プロジェクトをビルドしてパッケージ化します。

gulp bundle --ship && gulp package-solution --ship

次に、エクスプローラーでプロジェクト フォルダーを開き、sharepoint/solution フォルダーに移動します。

macOS Finder で開かれた 'sharepoint/solution' プロジェクト フォルダー

Web ブラウザーで、Office 365 テナントのテナントアプリ カタログに移動します。

Web ブラウザーに表示されるテナント アプリ カタログ

エクスプローラーからテナントのアプリ カタログにドラッグ アンド ドロップして、新しく生成された.sppkg** ファイルを追加します。

テナントのアプリ カタログを示す Web ブラウザーの上部に表示される macOS Finder ウィンドウ

ダイアログが表示されたら、[このソリューションを組織内のすべてのサイトで使用できるようにする] チェック ボックスをオンにします。 また、[サービス プリンシパル アクセス許可管理ページ] に移動して、保留中のアクセス許可を承認する必要があることにも注意してください。 [展開] ボタンを選択して、展開を確認します。

エンタープライズ API へのアクセスを許可する

Web ブラウザーでテナント管理サイトに移動するために、Office 365 アプリ起動ツールで [管理] オプションを選択します。

Office 365 アプリ起動ツールのメニューで強調表示された [管理] オプション

メニューの [管理センター] グループから、[SharePoint] を選択します。

Office 365 管理センターのメニューで強調表示された [SharePoint] オプション

SharePoint 管理センターで、[新しい SharePoint 管理センターのプレビューをお試しください] リンクを使用して、新しい SharePoint 管理センターのプレビューに移動します。

SharePoint 管理センターで強調表示された [新しい SharePoint 管理センター プレビューをお試しください] リンク

新しい管理センターで、メニューから [API 管理] オプションを選択します。

新しい SharePoint Online 管理センターのメニューで強調表示された [API の管理] オプション

[API 管理] ページの [承認待ち] グループで、contoso-api API にアクセスするために新しく追加されたアクセス許可要求を選択します。

新しい SharePoint Online 管理センターの [API の管理] ページで強調表示された、アクセス許可要求の横の選択ボタン

次に、ツールバーから [承認または拒否する] オプションを選択します。

新しい SharePoint Online 管理センターの [API の管理] ページのツールバーで強調表示された [承認または拒否する] オプション

作業ウィンドウで [承認] ボタンを選択して、API へのアクセスを許可します。

新しい SharePoint Online 管理センターで API 要求を管理するためのサイド パネルで強調表示された [承認] ボタン

Orders Web パーツをページに追加する

すべてが正常に動作していることを確認するには、前の手順で作成した Orders Web パーツをページに追加します。

Web ブラウザーで、テナント内のサイトに移動します。 ツールバーから [編集] オプションを選択します。

モダン チーム サイトのツールバーで強調表示された [編集] ボタン

キャンバスで、Web パーツを追加するセクションを選択します。

Web ブラウザーで強調表示されたページのセクション

+ オプションを選択してツールボックスを開きます。 Orders Web パーツをすばやく見つけるために、検索ボックスに Orders と入力します。

ツールボックスに 「Orders」と入力します。ツールボックスに表示される注文 Web パーツ

Orders Web パーツを選択してページに追加します。 エンタープライズ API から取得された注文のリストが表示されるはずです。

SharePoint ページに表示された、エンタープライズ API から取得された最近の注文の一覧