OAuth を使用して Microsoft Dataverse に対する認証を実行する

完了

Microsoft Dataverseでは、認証基準として OAuth 2.0 が使用されています。 OAuth 2.0 は、リソースに対してクライアント アプリケーションを認証してアクセス権を付与するための業界標準です。

認証と認可

認証とは、ユーザーまたはプロセスの ID を検証するプロセスやアクションのことです。 この検証プロセスに使用される Microsoft のソリューションは、Microsoft Entra ID です。 Entra ID では、ユーザーやプロセスの ID を検証するための多くのオプションがサポートされています。 ユーザー名とパスワードの管理は難しい (リスクの高い) プロセスになる可能性があるので、ID プロバイダーを抽象化することは、懸念事項を分離するための効果的な手段となります。

メモ

Microsoft Entra ID は Azure Active Directory の新しい名称です。 すべてのライセンスおよび機能は変わりません。

承認とは、認証済みのユーザーに対し、リソースへのアクセスが承認されているかどうかを確認するプロセスやアクションのことです。 現在、Dataverse の承認は Entra ID テナント レベルで実施されていますが、詳細なアクセス許可の管理は、現在サインインしているユーザーに基づいてアプリケーションに委任されます。 したがって、アプリレベルのセキュリティは OAuth 2.0 を使用して制御するのではなく、Dataverse セキュリティ ロール で処理され、Power Apps 管理センターでユーザーに割り当てられます。

認証と認可の概念の詳細については、認証の基本 を参照してください。

Dataverse アプリを Entra ID で登録する

Dataverse に正常に接続するには、まずアプリを Entra ID で登録する必要があります。この操作は、Azure Portal で実行できます。 作成するアプリの種類に応じて、構成に使用できる設定 (Web アプリか、デバイスにネイティブにインストールされるネイティブ アプリか) が異なります。 それぞれの種類で必要となる設定について詳しくは、「アプリ登録の種類」を参照してください。

アプリを Entra ID で登録するには、Entra ID (Azure Active Directory) メニューのアプリ登録セクションに移動し、新規登録を選択します。

Entra ID メニューの [アプリ登録] セクション、および [新規登録] を選択したスクリーンショット。

アプリケーションの名前と、必要なアカウント アクセスの種類を指定します。 Web アプリを登録する場合は、認証セクションに移動し、種類を Web に設定した後、リダイレクト URI を入力して、リダイレクト URI を指定します。

ユーザー向けの表示名、アカウント タイプ、およびリダイレクト URL のスクリーンショット。

次の一覧は、どのような場合にどの種類のアカウントを使用するかについてまとめたものです。

  • この組織のディレクトリ内のアカウントのみ (シングル テナント)

    ディレクトリ内のすべてのユーザー アカウントとゲスト アカウントが、アプリケーションまたは API を使用できます。

    このオプションは、対象ユーザーが組織の内部ユーザーである場合に使用します。

  • 任意の Entra ID ディレクトリ内のアカウント (任意のディレクトリ - マルチテナント型)

    Microsoft の職場または学校アカウントを持つすべてのユーザーが、アプリケーションまたは API を使用できます (Microsoft 365 を使用する学校や企業を含む)。

    このオプションは、対象ユーザーが企業や教育機関の顧客である場合で、かつマルチテナント機能を有効にする場合に使用します。

  • 任意の組織ディレクトリ内のアカウント (任意の Entra ID ディレクトリ - マルチテナント型) と個人の Microsoft アカウント (Skype、Xbox など)

    職場、学校、または個人用の Microsoft アカウントを持つすべてのユーザーが、アプリケーションまたは API 使用できます。 これには、Microsoft 365 を使用する学校や企業に加え、Xbox や Skype などのサービスにログインするために使用される個人用のアカウントが含まれます。

アプリケーション設定の複雑さに応じて、その他の認証設定を構成することもできます。 このタスクを実行する手順については、Entra ID のドキュメントを参照してください。

Web API を使用した Dataverse へのアクセス

Dataverse へのアクセスはすべて、サインイン ユーザーのコンテキストで行われます。 これは、通常の対話型ユーザーでも、サーバー間 (S2S) 認証を使用する非対話型ユーザーでもかまいません。

アプリケーションが対話型ユーザーの代わりに Dataverse にアクセスする場合、委任されたアクセス許可で Dataverse にアクセスするには、登録済みのアプリケーションを構成して API のアクセス許可を付与する必要があります。 アプリケーションが Dataverse に直接アクセスする場合、Entra ID アプリケーションの登録に関連付けられたアプリケーション ユーザーを Dataverse で作成する必要があります。 S2S 認証を使用する場合、Dataverse API の委任されたアクセス許可は必須ではありません。

いずれにしても、認証されたユーザーには、Web API を使用して実行される操作を許可するユーザーに関連付けられている Dataverse セキュリティ ロールが必要です。

API のアクセス許可の構成

アプリケーションがサインイン ユーザーの代わりに Dataverse にアクセスする場合、登録済みアプリケーションで API のアクセス許可タブに移動し、Dataverse 環境へのユーザー偽装アクセス権がアプリケーションに付与されていることを確認します。

[API のアクセス許可の要求] タブのスクリーンショット。

ラベルは Dynamics CRM になっていますが、これは Dataverse の前身の製品名です。

[API のアクセス許可の要求] タブで、委任されたアクセス許可および user_impersonation が選択されているスクリーンショット。

Dataverse アプリケーション ユーザーの構成

S2S 認証を使用する場合、各 Dataverse 環境で Dataverse アプリケーション ユーザーを構成する必要があります。Web API を使用してアクセスします。

Dataverse アプリケーション ユーザーの構成は、システム管理者として Power Platform 管理センターから行います。

Entra ID からアプリケーションを追加しているスクリーンショット。

管理センターからは次の手順を実行できます。

  • 新しいアプリケーション ユーザーを作成する

  • アプリケーション ユーザーと Entra ID アプリまたはマネージド ID を関連付ける

  • 適用される Dataverse セキュリティ ロールを構成する

詳しい手順については、「Power Platform 管理センターでアプリケーション ユーザーを管理する」を参照してください。

認証ライブラリを使用した接続

アプリケーションを登録したら、いずれかの Microsoft ID プラットフォーム認証ライブラリ を使用して認証を実行し、Web API で使用するアクセス トークンを取得します。

Microsoft 認証ライブラリ (MSAL) を使用する強化されたクイック スタート サンプルから抜粋したコードを以下に示します。 以下の OAuthMessageHandler クラスは、HttpClient のコンストラクターに渡される DelegatingHandler から派生したクラスを実装します。 このハンドラーを使用して HttpClient.SendAsync メソッドを上書きすると、AcquireToken* メソッド呼び出しによって、Http クライアントから送信された各要求でアクセス トークンが更新されるようになります。

class OAuthMessageHandler : DelegatingHandler
{
  private AuthenticationHeaderValue authHeader;
  public OAuthMessageHandler(string serviceUrl, string clientId, string redirectUrl, string username, string password, HttpMessageHandler innerHandler)
  : base(innerHandler)
  {
    //Build Microsoft.Identity.Client (MSAL) OAuth Token Request
    var clientApplication = PublicClientApplicationBuilder.Create(clientId)
    .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
    .WithRedirectUri(redirectUrl)
    .Build();
    var scope = serviceUrl + "//.default";
    string[] scopes = { scope };
    AuthenticationResult authBuilderResult;
    if (username != string.Empty && password != string.Empty)
    {
      //Make silent Microsoft.Identity.Client (MSAL) OAuth Token Request
      var securePassword = new SecureString();
      foreach (char ch in password) securePassword.AppendChar(ch);
      authBuilderResult = clientApplication.AcquireTokenByUsernamePassword(scopes, username, securePassword).ExecuteAsync().Result;
    }
    else
    {
      //Popup authentication dialog box to get token
      authBuilderResult = clientApplication.AcquireTokenInteractive(scopes).ExecuteAsync().Result;
    }
      //Note that an Entra ID access token has a finite lifetime, default expiration is 60 minutes.
      authHeader = new AuthenticationHeaderValue("Bearer", authBuilderResult.AccessToken);
    }
  protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
  {
    request.Headers.Authorization = authHeader;
    return base.SendAsync(request, cancellationToken);
  }
}

次に、ヘルパー メソッドにより、ハンドラーを使用して HttpClient インスタンスを取得できます。

static HttpClient GetHttpClient(string url, string clientId, string redirectUrl, string version = "v9.2")
{
  try
  {
    HttpMessageHandler messageHandler = new OAuthMessageHandler(url, clientId, redirectUrl, "", "",
    new HttpClientHandler());
    HttpClient httpClient = new HttpClient(messageHandler)
    {
      BaseAddress = new Uri(string.Format("{0}/api/data/{1}/", url, version)),
      Timeout = new TimeSpan(0, 2, 0) //2 minutes
    };
  return httpClient;
  }
  catch (Exception)
  {
    throw;
  }
}

最後に、クライアント インスタンスを使用して Web API 呼び出しを行います。

using (HttpClient client = GetHttpClient("https://yourenvname.api.crm.dynamics.com", "51f81489-12ee-4a9e-aaae-a2591f45987d", "http://localhost:8080"))
{
  // Use the WhoAmI function
  var response = client.GetAsync("WhoAmI").Result;
  if (response.IsSuccessStatusCode)
  {
    //Get the response content and parse it.
    JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
    Guid userId = (Guid)body["UserId"];
    Console.WriteLine("Your UserId is {0}", userId);
  }
  else
  {
    Console.WriteLine("The request failed with a status of '{0}'", response.ReasonPhrase);
  }
  Console.WriteLine("Press any key to exit.");
  Console.ReadLine();
}

これで、Dataverse 環境に正常に接続できるアプリが登録されました。 登録済みアプリに接続して使用し、Web API の操作にアクセスする簡単な例も用意されています。