アプリで Microsoft Authentication Library (MSAL) を使用して認証する方法

クラスターでプログラムで認証するには、Azure Data Explorer に固有のアクセス トークン Microsoft Entra ID 要求する必要があります。 このアクセス トークンは、クラスターに要求を発行するときに ID の証明として機能します。 Microsoft Authentication Library (MSAL) flows のいずれかを使用してアクセス トークンを作成できます。

この記事では、MSAL を使用してクラスターのプリンシパルを認証する方法について説明します。 プリンシパルを認証するために MSAL を直接使用することは、主に、 On-behalf-of (OBO) 認証 または Single Page Application (SPA) 認証を必要とする Web アプリケーションに関連します。 それ以外の場合は、認証プロセスを簡略化するため、 Kusto クライアント ライブラリ を使用することをお勧めします。

この記事では、主要な認証シナリオ、認証を成功させるために提供する情報、および認証に MSAL を使用する方法について説明します。

認証シナリオ

認証の主なシナリオは次のとおりです。

  • ユーザー認証: 人間のユーザーの ID を確認するために使用されます。

  • アプリケーション認証: 構成された資格情報を使用して、人の介入なしにリソースにアクセスする必要があるアプリケーションの ID を検証するために使用されます。

  • On-behalf-of (OBO) 認証: アプリケーションが、Kusto サービスにアクセスするためのトークンを使用して、そのアプリケーションのトークンを交換できるようにします。 このフローは MSAL で実装する必要があります。

  • シングル ページ アプリケーション (SPA) 認証: クライアント側の SPA Web アプリケーションがユーザーをサインインさせ、クラスターにアクセスするためのトークンを取得できるようにします。 このフローは MSAL で実装する必要があります。

ユーザーとアプリケーションの認証には、 Kusto クライアント ライブラリを使用することをお勧めします。 OBO および SPA 認証では、Kusto クライアント ライブラリを使用できません。

認証パラメーター

トークン取得プロセス中に、クライアントは次のパラメーターを指定する必要があります。

パラメーター名 説明
Resource ID Microsoft Entra アクセス トークンを発行するリソース ID。 リソース ID は、ポート情報とパスのないクラスター URI です。

: help クラスターのリソース ID が https://help.kusto.windows.net
Microsoft Entra テナント ID Microsoft Entra ID はマルチテナント サービスであり、すべての組織は、ユーザー アカウントやアプリケーションなどのセキュリティ関連のオブジェクトを保持するディレクトリと呼ばれるオブジェクトを作成できます。 Microsoft Entra ID では多くの場合、ディレクトリをテナントと呼びます。 各テナントには、GUID の形式でテナント ID があります。 多くの場合、組織のドメイン名を使用して Microsoft Entra テナントを識別することもできます。

: 組織 "Contoso" には、テナント ID 12345678-a123-4567-b890-123a456b789c とドメイン名 contoso.comがあります。
Microsoft Entra 機関 URI 認証に使用されるエンドポイント。 Microsoft Entra ディレクトリまたはテナントによって、Microsoft Entra 機関 URI が決定されます。 URI はhttps://login.microsoftonline.com/{tenantId}{tenantId}テナント ID またはドメイン名です。

: たとえば、 https://login.microsoftonline.com/12345678-a123-4567-b890-123a456b789c

Note

Microsoft Entra サービス エンドポイントは、国内クラウドでは変更されます。 国内クラウドにデプロイされた Azure Data Explorer サービスを使用する場合は、対応する国内クラウドの Microsoft Entra サービス エンドポイントを設定します。

MSAL でユーザー認証を実行する

次のコード サンプルは、MSAL を使用してクラスターの承認トークンを取得する方法を示しています。 承認は、対話型サインイン UI を起動する方法で行われます。 appRedirectUriは、認証が正常に完了した後に Microsoft Entra ID がリダイレクトされる URL です。 MSAL は、このリダイレクトから承認コードを抽出します。

var kustoUri = "https://<clusterName>.<region>.kusto.windows.net";

var authClient = PublicClientApplicationBuilder.Create("<appId>")
    .WithAuthority($"https://login.microsoftonline.com/<appTenant>")
    .WithRedirectUri("<appRedirectUri>")
    .Build();

var result = authClient.AcquireTokenInteractive(
    new[] { $"{kustoUri}/.default" } // Define scopes for accessing Azure Data Explorer cluster
).ExecuteAsync().Result;

var bearerToken = result.AccessToken;

var request = WebRequest.Create(new Uri(kustoUri));
request.Headers.Set(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}", "Bearer", bearerToken));

Note

  • 可能な限り、 Kusto クライアント ライブラリ を使用することをお勧めします。 これらのライブラリを使用すると、Kusto 接続文字列で認証プロパティを指定できるため、認証プロセスが簡略化されます。
  • Kusto クライアント ライブラリを使用すると、Microsoft Entra トークンはユーザーのコンピューター上のローカル トークン キャッシュに格納され、資格情報の入力を求められる回数を減らすことができます。 キャッシュ ファイルは %APPDATA%\Kusto\userTokenCache.data サインインしているユーザーのみがアクセスできます。

MSAL を使用してアプリケーション認証を実行する

次のコード サンプルは、MSAL を使用してクラスターの承認トークンを取得する方法を示しています。 このフローでは、プロンプトは表示されません。 アプリケーションは Microsoft Entra ID で登録され、Microsoft Entra ID によって発行されたアプリ キーまたは X509v2 証明書を持っている必要があります。 アプリケーションを設定するには、「 Microsoft Entra アプリケーションをプロビジョニングするを参照してください。

var kustoUri = "https://<clusterName>.<region>.kusto.windows.net";

var authClient = ConfidentialClientApplicationBuilder.Create("<appId>")
    .WithAuthority($"https://login.microsoftonline.com/<appTenant>")
    .WithClientSecret("<appKey>") // Can be replaced by .WithCertificate to authenticate with an X.509 certificate
    .Build();

var result = authClient.AcquireTokenForClient(
    new[] { $"{kustoUri}/.default" } // Define scopes for accessing Azure Data Explorer cluster
).ExecuteAsync().Result;
var bearerToken = result.AccessToken;

var request = WebRequest.Create(new Uri(kustoUri));
request.Headers.Set(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}", "Bearer", bearerToken));

Note

可能な限り、 Kusto クライアント ライブラリ を使用することをお勧めします。 これらのライブラリを使用すると、Kusto 接続文字列で認証プロパティを指定できるため、認証プロセスが簡略化されます。

On-Behalf-of (OBO) 認証を実行する

代理認証 は、Web アプリケーションまたはサービスがユーザーまたはアプリケーションとクラスターの間のメディエーターとして機能する場合に関連します。

このシナリオでは、任意のリソースの Microsoft Entra アクセス トークンがアプリケーションに送信されます。 次に、アプリケーションはそのトークンを使用して、Azure Data Explorer リソースの新しい Microsoft Entra アクセス トークンを取得します。 その後、アプリケーションは、元の Microsoft Entra アクセス トークンによって示されたプリンシパルに代わってクラスターにアクセスできます。 このフローは、 OAuth 2.0 の代理認証フローと呼ばれます。 通常、Microsoft Entra ID を使用した複数の構成手順が必要です。場合によっては、Microsoft Entra テナントの管理者から特別な同意が必要になる場合があります。

代理認証を実行するには:

  1. Microsoft Entra アプリケーションをプロビジョニングします

  2. アプリケーションとクラスターの間に信頼関係を確立します。 これを行うには、「委任されたアクセス許可の構成の手順に従います。

  3. サーバー コードで、MSAL を使用してトークン交換を実行します。

    var kustoUri = "https://<clusterName>.<region>.kusto.windows.net";
    
    var authClient = ConfidentialClientApplicationBuilder.Create("<appId>")
        .WithAuthority($"https://login.microsoftonline.com/<appTenant>")
        .WithClientSecret("<appKey>") // Can be replaced by .WithCertificate to authenticate with an X.509 certificate
        .Build();
    
    var result = authClient.AcquireTokenOnBehalfOf(
        new[] { $"{kustoUri}/.default" }, // Define scopes for accessing your cluster
        new UserAssertion("<userAccessToken>") // Encode the "original" token that will be used for exchange
    ).ExecuteAsync().Result;
    var accessTokenForAdx = result.AccessToken;
    
  4. トークンを使用してクエリを実行します。 次に例を示します。

    var request = WebRequest.Create(new Uri(kustoUri));
    request.Headers.Set(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}", "Bearer", accessTokenForAdx));
    

シングル ページ アプリケーション (SPA) 認証の実行

SPA Web クライアントの認証には、 OAuth 承認コード フローを使用します。

このシナリオでは、アプリが Microsoft Entra ID にサインインするようにリダイレクトされます。 次に、Microsoft Entra ID は URI の承認コードを使用してアプリにリダイレクトします。 その後、アプリはトークン エンドポイントに対してアクセス トークンを取得する要求を行います。 トークンは 24 時間有効です。この間、クライアントはトークンをサイレントに取得することでトークンを再利用できます。

Microsoft ID プラットフォームには、などのさまざまなユース ケースに関する詳細なチュートリアルがありますReactAngularJavaScript

Web クライアントの認証を設定するには:

  1. Microsoft Entra アプリケーションをプロビジョニングします

  2. 認証コード フローを使用して MSAL.js 2.0 の説明に従ってアプリを構成

  3. MSAL.js 2.0 ライブラリを使用してユーザーをサインインさせ、クラスターに対して認証します。 Microsoft ID プラットフォームには、などのさまざまなユース ケースに関する詳細なチュートリアルがありますReactAngularJavaScript

    次の例では、MSAL.js ライブラリを使用して Azure Data Explorer にアクセスします。

    import * as msal from "@azure/msal-browser";
    
    const msalConfig = {
      auth: {
        clientId: "<AAD client application ID>",
        authority: "https://login.microsoftonline.com/<AAD tenant ID>",
      },
    };
    
    const msalInstance = new msal.PublicClientApplication(msalConfig);
    const myAccounts = msalInstance.getAllAccounts();
    
    // If no account is logged in, redirect the user to log in.
    if (myAccounts === undefined || myAccounts.length === 0) {
      try {
        await msalInstance.loginRedirect({
          scopes: ["https://help.kusto.windows.net/.default"],
        });
      } catch (err) {
        console.error(err);
      }
    }
    const account = myAccounts[0];
    const name = account.name;
    window.document.getElementById("main").innerHTML = `Hi ${name}!`;
    
    // Get the access token required to access the specified Azure Data Explorer cluster.
    const accessTokenRequest = {
      account,
      scopes: ["https://help.kusto.windows.net/.default"],
    };
    let acquireTokenResult = undefined;
    try {
      acquireTokenResult = await msalInstance.acquireTokenSilent(accessTokenRequest);
    } catch (error) {
      if (error instanceof InteractionRequiredAuthError) {
        await msalInstance.acquireTokenRedirect(accessTokenRequest);
      }
    }
    
    const accessToken = acquireTokenResult.accessToken;
    
    // Make requests to the specified cluster with the token in the Authorization header.
    const fetchResult = await fetch("https://help.kusto.windows.net/v2/rest/query", {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
      },
      method: "POST",
      body: JSON.stringify({
        db: "Samples",
        csl: "StormEvents | count",
      }),
    });
    const jsonResult = await fetchResult.json();
    
    // The following line extracts the first cell in the result data.
    const count = jsonResult.filter((x) => x.TableKind === "PrimaryResult")[0].Rows[0][0];