如何在應用程式中使用 Microsoft 驗證程式庫 (MSAL) 進行驗證

若要以程式設計方式向叢集進行驗證,您必須向 Azure Data Explorer特定的Microsoft Entra識別碼要求存取權杖。 此存取權杖可作為向叢集發出要求時的身分識別證明。 您可以使用其中一個 Microsoft 驗證程式庫 (MSAL) 流程 來建立存取權杖。

本文說明如何使用 MSAL 向叢集驗證主體。 直接使用 MSAL 來驗證主體主要與需要 代理 (OBO) 驗證單頁應用程式 (SPA) 驗證的 Web 應用程式相關。 針對其他情況,建議您在簡化驗證程式時使用 Kusto 用戶端程式庫

在本文中,瞭解主要驗證案例、提供成功驗證的資訊,以及使用 MSAL 進行驗證。

驗證案例

主要驗證案例如下所示:

  • 使用者驗證:用來驗證人類使用者的身分識別。

  • 應用程式驗證:用來驗證需要存取資源的應用程式身分識別,而不需使用已設定的認證人為介入。

  • 代表 (OBO) 驗證:允許應用程式以權杖交換權杖給該應用程式,以存取 Kusto 服務。 此流程必須使用 MSAL 實作。

  • 單頁應用程式 (SPA) 驗證:允許用戶端 SPA Web 應用程式登入使用者,並取得權杖以存取您的叢集。 此流程必須使用 MSAL 實作。

針對使用者和應用程式驗證,我們建議使用 Kusto 用戶端程式庫。 針對 OBO 和 SPA 驗證,無法使用 Kusto 用戶端程式庫。

驗證參數

在權杖擷取程式期間,用戶端必須提供下列參數:

參數名稱 描述
資源識別碼 要發出Microsoft Entra存取權杖的資源識別碼。 資源識別碼是沒有埠資訊和路徑的叢集 URI。

範例:叢集的資源識別碼 helphttps://help.kusto.windows.net
Microsoft Entra租使用者識別碼 Microsoft Entra識別碼是多租使用者服務,而且每個組織都可以建立稱為目錄的物件,該目錄會保存安全性相關物件,例如使用者帳戶和應用程式。 Microsoft Entra識別碼通常會將目錄稱為租使用者。 每個租使用者都有 GUID 形式的租使用者識別碼。 在許多情況下,組織的功能變數名稱也可以用來識別Microsoft Entra租使用者。

範例:組織 「Contoso」 可能有租使用者識別碼 12345678-a123-4567-b890-123a456b789c 和功能變數名稱 contoso.com
Microsoft Entra授權單位 URI 用於驗證的端點。 Microsoft Entra目錄或租使用者會決定Microsoft Entra授權單位 URI。 URI 是 https://login.microsoftonline.com/{tenantId} 租使用者識別碼或功能變數名稱的位置 {tenantId}

例如https://login.microsoftonline.com/12345678-a123-4567-b890-123a456b789c 例如 。

注意

Microsoft Entra國家雲端中的服務端點變更。 使用部署在國家雲端中的 Azure Data Explorer服務時,請設定對應的國家雲端Microsoft Entra服務端點。

使用 MSAL 執行使用者驗證

下列程式碼範例示範如何使用 MSAL 來取得叢集的授權權杖。 授權是以啟動互動式登入 UI 的方式完成。 appRedirectUri是驗證成功完成之後,Microsoft Entra識別碼重新導向的 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));

注意

  • 建議您盡可能使用 Kusto 用戶端程式庫 。 這些程式庫可讓您在Kusto 連接字串中提供驗證屬性,以簡化驗證程式。
  • 使用 Kusto 用戶端程式庫時,Microsoft Entra權杖會儲存在使用者電腦上的本機權杖快取中,以減少提示輸入認證的次數。 快取檔案是 %APPDATA%\Kusto\userTokenCache.data, 而且只能由登入的使用者存取。

使用 MSAL 執行應用程式驗證

下列程式碼範例示範如何使用 MSAL 來取得叢集的授權權杖。 在此流程中,不會顯示提示。 應用程式必須以Microsoft Entra識別碼註冊,並具有應用程式金鑰或Microsoft Entra識別碼所發行的 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));

注意

建議您盡可能使用 Kusto 用戶端程式庫 。 這些程式庫可讓您在Kusto 連接字串中提供驗證屬性,以簡化驗證程式。

執行代理者 (OBO) 驗證

當您的 Web 應用程式或服務做為使用者或應用程式與叢集之間的中繼程式時,代理者驗證會相關。

在此案例中,應用程式會針對任意資源傳送Microsoft Entra存取權杖。 然後,應用程式會使用該權杖來取得 Azure Data Explorer 資源的新Microsoft Entra存取權杖。 然後,應用程式可以代表原始Microsoft Entra存取權杖所指示的主體來存取叢集。 此流程稱為 OAuth 2.0 代理者驗證流程。 它通常需要具有Microsoft Entra識別碼的多個設定步驟,在某些情況下,可能需要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識別碼。 然後,Microsoft Entra識別碼會重新導向回具有 URI 中授權碼的應用程式。 然後,應用程式會對權杖端點提出要求,以取得存取權杖。 權杖的有效期間為 24 小時,用戶端可以透過無訊息方式取得權杖來重複使用權杖。

Microsoft 身分識別平臺針對不同的使用案例提供詳細的教學課程,例如ReactAngularJavaScript

若要設定 Web 用戶端的驗證:

  1. 布建Microsoft Entra應用程式

  2. 使用驗證碼流程MSAL.js 2.0中所述設定應用程式。

  3. 使用 MSAL.js 2.0 程式庫來登入使用者,並驗證您的叢集。 Microsoft 身分識別平臺針對不同的使用案例提供詳細的教學課程,例如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];