Authenticate with Azure AD for access (2023)

  • Article

The recommended way to access your cluster is by authenticating to theAzure Active Directory (Azure AD) service; doing so guarantees privacy of the accessing principal's directory credentials.

To do so, the client performs a two-steps process:

  1. In the first step, the client:
    1. Communicates with the Azure AD service.
    2. Authenticates to the Azure AD service.
    3. Requests an access token issued specifically for your cluster.
  2. In the second step, the client issues requests to your cluster, providing the access token acquired in the first step as a proof of identity to your cluster.

The request is then executed on behalf of the security principal for which Azure AD issued the access token.All authorization checks are performed using this identity.

In most cases, the recommendation is to use one of the Kusto SDKs to access theservice programmatically, as they remove much of the hassle of implementing theflow (and much more). For more information, see the .NET SDK.The authentication properties are then set by the Kusto connection string.If that isn't possible, continue reading for detailed information on how to implement this flow yourself.

The main authenticating scenarios are:

  • A client application authenticating a signed-in user.In this scenario, an interactive (client) application triggers an Azure AD promptto the user for credentials (such as username and password).See user authentication,

  • A "headless" application.In this scenario, an application is running with no user present to providecredentials. Instead the application authenticates as "itself" to Azure ADusing some credentials it has been configured with.See application authentication.

  • On-behalf-of authentication.In this scenario, sometimes called the "web service" or "web app" scenario,the application gets an Azure AD access token from another application, and then"converts" it to another Azure AD access token that can be used to access your cluster.In other words, the application acts as a mediator between the user or applicationthat provided credentials and the engine service.See on-behalf-of authentication.

Specifying the Azure AD resource

When acquiring an access token from Azure AD, the client must indicate which Azure AD resourcethe token should be issued to. The Azure AD resource of an endpoint is theURI of the endpoint, barring the port information and the path. For example:

https://help.kusto.windows.net

Alternatively, clients may also request an access token with a cloud-static resource ID, such as

https://kusto.kusto.windows.net

(for public cloud services). Clients doing so must make sure that they only send this access tokento a Kusto service endpoint, based on the host name suffix (here, kusto.windows.net).Sending the access token to untrusted service endpoints might result in token leakage, allowing thereceiving service to perform operations on any Kusto service endpoint to which theprincipal has access.

Specifying the Azure AD tenant ID

Azure AD is a multi-tenant service, and every organization can create an object calleddirectory in Azure AD. The directory object holds security-related objects suchas user accounts, applications, and groups. Azure AD often refers to the directoryas a tenant. Azure AD tenants are identified by a GUID (tenant ID). In manycases, Azure AD tenants can also be identified by the domain name of the organization.

For example, an organization called "Contoso" might have the tenant ID4da81d62-e0a8-4899-adad-4349ca6bfe24 and the domain name contoso.com.

Specifying the Azure AD authority endpoint

Azure AD has many endpoints for authentication:

  • When the tenant hosting the principal being authenticated is known(in other words, when one knows which Azure AD directory the user or applicationare in), the Azure AD endpoint is https://login.microsoftonline.com/{tenantId}.Here, {tenantId} is either the organization's tenant ID in Azure AD, or itsdomain name (for example, contoso.com).

  • When the tenant hosting the principal being authenticated isn't known,the "common" endpoint can be used by replacing the {tenantId} abovewith the value common.

Note

The Azure AD service endpoint used for authentication is also called Azure AD authority URLor simply Azure AD authority.

Note

The Azure AD service endpoint changes in national clouds. When working with a clusterdeployed in a national cloud, please set the corresponding national cloud Azure AD service endpoint.To change the endpoint, set an environment variable AadAuthorityUri to the required URI.

Azure AD local token cache

While using the Kusto SDK, the Azure AD tokens are stored on the local machine in aper-user token cache (a file called %APPDATA%\Kusto\userTokenCache.data which canonly be accessed or decrypted by the signed-in user.) The cache is inspectedfor tokens before prompting the user for credentials, reducing thenumber of times a user is prompted for credentials.

Note

The Azure AD token cache reduces the number of interactive prompts, but doesn'treduce them completely. Additionally, users cannot anticipate in advance whenthey will be prompted for credentials.This means that one must not attempt to use a user account to authenticate ifthere's a need to support non-interactive logons (such as when scheduling tasksfor example), because when the time comes for prompting the logged on user forcredentials that prompt will fail if running under non-interactive logon.

User authentication

The easiest way to access your cluster with user authentication is to use the Kusto SDKand set the Federated Authentication property of the connection string totrue. The first time the SDK is used to send a request to the service the userwill be presented with a sign-in form to enter the Azure AD credentials. Following asuccessful authentication the request will be sent.

Applications that don't use the Kusto SDK can still use the Microsoft Authentication Library (MSAL) instead of implementing the Azure AD service security protocol client. See Azure AD and OpenID Connectfor an example of doing so from a .NET application.

If your application is intended to serve as front-end and authenticate users for an Azure Data Explorer cluster, the application must be granted delegated permissions on Azure Data Explorer.The full step-by-step process is described in Configure delegated permissions for the application registration.

The following brief code snippet demonstrates using Microsoft Authentication Library (MSAL) to acquire an Azure AD user token to access a cluster (launches sign-in UI):

var kustoUri = "https://<clusterName>.<region>.kusto.windows.net";// Create a public authentication client for Azure AD:var authClient = PublicClientApplicationBuilder.Create("<appId>") .WithAuthority($"https://login.microsoftonline.com/<appTenant>") .WithRedirectUri("<appRedirectUri>") .Build();// Acquire user token for the interactive user for Azure Data Explorer:var result = authClient.AcquireTokenInteractive( new[] { $"{kustoUri}/.default" } // Define scopes for accessing Azure Data Explorer cluster).ExecuteAsync().Result;// Extract Bearer access token var bearerToken = result.AccessToken;// Create an HTTP request and set the Authorization header on your request:var request = WebRequest.Create(new Uri(kustoUri));request.Headers.Set(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}", "Bearer", bearerToken));

Application authentication

The following brief code snippet demonstrates using Microsoft Authentication Library (MSAL) to acquire an Azure AD application token to access a cluster. In this flow no prompt is presented, andthe application must be registered with Azure AD and equipped with credentials neededto perform application authentication (such as an app key issued by Azure AD,or an X509v2 certificate that has been pre-registered with Azure AD).

var kustoUri = "https://<clusterName>.<region>.kusto.windows.net";// Create a confidential authentication client for Azure AD: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();// Acquire aplpication token for Azure Data Explorer:var result = authClient.AcquireTokenForClient( new[] { $"{kustoUri}/.default" } // Define scopes for accessing Azure Data Explorer cluster).ExecuteAsync().Result;// Extract Bearer access token var bearerToken = result.AccessToken;// Create an HTTP request and set the Authorization header on your request:var request = WebRequest.Create(new Uri(kustoUri));request.Headers.Set(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "{0} {1}", "Bearer", bearerToken));

On-behalf-of authentication

In this scenario, an application was sent an Azure AD access token for some arbitraryresource managed by the application, and it uses that token to acquire a new Azure ADaccess token for the resource so that the application could access Kustoon behalf of the principal indicated by the original Azure AD access token.

This flow is called theOAuth2 token exchange flow.It generally requires multiple configuration steps with Azure AD, and in some cases(depending on the Azure AD tenant configuration) might require special consent fromthe administrator of the Azure AD tenant.

Step 1: Establish trust relationship between your application and your cluster

  1. Open the Azure portal and make sure that you'resigned-in to the correct tenant (see top/right corner for the identityused to sign in to the portal).

  2. On the resources pane, select Azure Active Directory, then App registrations.

  3. Locate the application that uses the on-behalf-of flow and open it.

  4. Select API permissions, then Add a permission.

  5. Search for the application named Azure Data Explorer and select it.

  6. Select user_impersonation / Access Kusto.

  7. Select Add permission.

Step 2: Perform token exchange in your server code

// Create a confidential authentication client for Azure AD: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();// Acquire on-behalf-of user token for the interactive user for Azure Data Explorer based on provided token:var result = authClient.AcquireTokenOnBehalfOf( new[] { "https://<clusterName>.<region>.kusto.windows.net/.default" }, // Define scopes for accessing Azure Data Explorer cluster new UserAssertion("<userAccessToken>") // Encode the "original" token that will be used for exchange).ExecuteAsync().Result;var accessTokenForAdx = result.AccessToken;

Step 3: Provide the token to Kusto client library and execute queries

// Create KustoConnectionStringBuilder using the previously acquired Azure AD tokenvar connectionStringBuilder = new KustoConnectionStringBuilder("https://<clusterName>.<region>.kusto.windows.net") .WithAadUserTokenAuthentication(accessTokenForAdx);// Create an ADX query client base on the conneciton string objectusing var queryClient = KustoClientFactory.CreateCslQueryProvider(connectionStringBuilder);// Execute queryvar queryResult = await queryClient.ExecuteQueryAsync("<databaseName>", "<query>", null);

Web Client (JavaScript) authentication and authorization

Azure AD application configuration

In addition to the standard steps for setting up an Azure AD application, you'll also need to enable the single-page application (SPA) setting on your Azure AD application. This enables OAuth authorization code flow with PKCE for obtaining tokens used by MSAL.js 2.0 (MSAL 1.0 used a less secure implicit grant flow). Use the MSAL 2.0 steps in the SPA app registration scenario to configure the app accordingly.

Details

When the client is a JavaScript code running in the user's browser, the auth code flow is used. The authentication flow consists of two stages:

  1. The app is redirected to sign in to Azure AD. Once signed in, Azure AD redirects back to the app with an authorization code in the URI.

  2. The app makes a request to the token endpoint to get the access token. The token is valid for 24 hour during which the client can reuse it by acquiring the token silently.

Like in the native client flow, there should be two Azure AD applications (server and client) with a configured relationship between them.

Note

  • The ID token is obtained by calling the PublicClientApplication.loginRedirect() method, and access tokens are obtained by calling PublicClientApplication.acquireTokenSilent(), or PublicClientApplication.acquireTokenRedirect() in case silent acquisition failed. MSAL 2.0 also supports PublicClientApplicationloginPopup(), but some browser block pop-ups which makes it less useful than a redirect.
  • MSAL 2.0 requires signing in (also known as getting an ID token) before any access token calls are made.

MSAL.js 2.0 has detailed sample apps for different frameworks such as React and Angular. For an example of how to use MSAL.js 2.0 to authenticate to a cluster using a React application, see the MSAL.js 2.0 React sample. For other frameworks, check the MSAL.js 2.0 documentation to find a sample app.

The following is a framework-independent code sample for connecting to the Help cluster.

  1. Create an instance of the MSAL PublicClientApplication:

    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);

    Important

    Make sure your application always calls handleRedirectPromise() whenever the page loads. This is because Azure AD adds the authorization code as part of the URI and the handleRedirectPromise() function extracts the authorization code from URI and caches it.

    await msalInstance.handleRedirectPromise();
  2. Add the code to sign in if the MSAL doesn't have any locally cached accounts. Note the use of scopes to redirect to the Azure AD page for providing your app with the permission required to access your cluster.

    const myAccounts = msalInstance.getAllAccounts();// If no account is logged in, redirect the user to log in.// no need for a return statement here, because the browser will redirect the user to the login page.if (myAccounts === undefined || myAccounts.length === 0) { try { await msalInstance.loginRedirect({ scopes: ["https://help.kusto.windows.net/.default"], }); } catch (err) { console.err(err); // handle error }}
  3. Add the code to call msalInstance.acquireTokenSilent() to get the actual access token required to access the specified cluster. If silent token acquisition fails, call acquireTokenRedirect() to get a new token.

     const account = myAccounts[0]; const name = account.name; window.document.getElementById("main").innerHTML = `HI ${name}!`; const accessTokenRequest = { account, scopes: ["https://help.kusto.windows.net/.default"], }; let acquireTokenResult = undefined; try { acquireTokenResult = await msalInstance.acquireTokenSilent( accessTokenRequest ); } catch (error) { // if our access / refresh / id token is expired we need redirect to AAD to get a new one. if (error instanceof InteractionRequiredAuthError) { await msalInstance.acquireTokenRedirect(accessTokenRequest); } } const accessToken = acquireTokenResult.accessToken;
  4. Finally, add code to make requests to the specified cluster. You must add the token in the Authorization attribute in the request header for the authentication to succeed. For example, the following code makes a request to run a query against the Samples database in the Help cluster.

    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];
Top Articles
Latest Posts
Article information

Author: Clemencia Bogisich Ret

Last Updated: 06/14/2023

Views: 6005

Rating: 5 / 5 (60 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Clemencia Bogisich Ret

Birthday: 2001-07-17

Address: Suite 794 53887 Geri Spring, West Cristentown, KY 54855

Phone: +5934435460663

Job: Central Hospitality Director

Hobby: Yoga, Electronics, Rafting, Lockpicking, Inline skating, Puzzles, scrapbook

Introduction: My name is Clemencia Bogisich Ret, I am a super, outstanding, graceful, friendly, vast, comfortable, agreeable person who loves writing and wants to share my knowledge and understanding with you.