Get Microsoft Entra ID (formerly Azure Active Directory) tokens for users by using MSAL

Important

This article describes how to manually create Microsoft Entra ID (formerly Azure Active Directory) tokens by using the Microsoft Authentication Library (MSAL).

Databricks does not recommend that you create Microsoft Entra ID (formerly Azure Active Directory) tokens for Azure Databricks users manually. This is because each Microsoft Entra ID token is short-lived, typically expiring within one hour. After this time, you must manually generate a replacement Microsoft Entra ID token. Instead, use one of the participating tools or SDKs that implement the Databricks client unified authentication standard. These tools and SDKs automatically generate and replace expired Microsoft Entra ID tokens for you, leveraging Azure CLI authentication.

Azure Databricks managed service principals are managed directly within Azure Databricks. Microsoft Entra ID managed service principals are managed in Microsoft Entra ID, which requires additional permissions. Databricks recommends that you use Azure Databricks managed service principals for most use cases. However, Databricks recommends that you use Microsoft Entra ID managed service principals in cases where you must authenticate with Azure Databricks and other Azure resources at the same time.

To create a Azure Databricks managed service principal instead of a Microsoft Entra ID managed service principal, see Manage service principals.

You can use the Microsoft Authentication Library (MSAL) to acquire Microsoft Entra ID access tokens programatically. This article describes basic usage of the MSAL library and required user inputs, with Python examples.

Note

MSAL replaces the Microsoft Entra ID Authentication Library (ADAL). All Microsoft support and development for ADAL, including security fixes, ended on June 30, 2022. See Migrate applications to the Microsoft Authentication Library (MSAL).

Tip

You might want to try using the Azure CLI instead of the MSAL to get Microsoft Entra ID tokens for users, as using the Azure CLI involves fewer steps. See Get Microsoft Entra ID (formerly Azure Active Directory) tokens for users by using the Azure CLI.

You can also define a service principal in Microsoft Entra ID and get a Microsoft Entra ID access token for the service principal rather than for a user. See Get Microsoft Entra ID (formerly Azure Active Directory) tokens for service principals.

Configure an app in Azure portal

Register an application with the Microsoft Entra ID endpoint in the Azure portal. Alternatively, you can use a Microsoft Entra ID app that is already registered. For more information, see Register an app by using the Azure portal.

  1. Sign in to the Azure portal.

    Note

    The portal to use is different depending on whether your Microsoft Entra ID application runs in the Azure public cloud or in a national or sovereign cloud. For more information, see National clouds.

  2. If you have access to multiple tenants, subscriptions, or directories, click the Directories + subscriptions (directory with filter) icon in the top menu to switch to the directory in which you want to register the application.

  3. Search for and select Microsoft Entra ID.

  4. Within Manage, select App registrations > New registration.

  5. For Name, enter a name for the application.

  6. In the Supported account types section, select Accounts in this organizational directory only (Single tenant).

  7. In the Redirect URI (optional) section, for Select a platform, select Public client/native (mobile & desktop) and enter a redirect URI. In the following example, the redirect URI value is http://localhost.

    Register app

  8. Click Register.

  9. On the application page’s Overview page, in the Essentials section, copy the following values:

    • Application (client) ID
    • Directory (tenant) ID
    • In Redirect URIs, the public client redirect URI that you entered earlier in this procedure.

    Azure registered app overview

  10. Add AzureDatabricks to the required permissions of the registered application. You must be an admin user to perform this step. If you encounter a permissions-related issue while you perform this action, contact your administrator for help.

    1. On the application page’s Overview page, on the Get Started tab, click View API permissions.

      Azure registered app settings

    2. Click Add a permission.

      Add required permissions to app

    3. In the Request API permissions pane, click the APIs my organization uses tab, search for AzureDatabricks, and then select it.

      Add AzureDatabricks API permission

    4. Enable the user_impersonation check box, and then click Add permissions.

      Azure app delegated permissions

    5. Click Grant admin consent for ### and then Yes. To perform this action, you must be an admin user or have the privilege to grant consent to the application. If you do not see Grant admin consent for ###, or if you skip this action, you must use the Authorization code flow (interactive) the first time you use the application to provide consent. After that, you can use the Username-password flow (programmatic) method.

      Add additional users and groups to app permissions

You can add additional users to the application. For more information, see Assign a user account to an enterprise application for Azure portal instructions or Assign users and groups to an application in Microsoft Entra ID (formerly Azure Active Directory) for PowerShell instructions. A user will not be able to obtain a token without required permissions.

Get a Microsoft Entra ID access token

To get a Microsoft Entra ID access token, you can use either the:

You must use the authorization code flow (interactive) to get the Microsoft Entra ID access token if:

  • Two factor authentication is enabled in Microsoft Entra ID.
  • Federated authentication is enabled in Microsoft Entra ID.
  • You are not granted consent to the registered application during application registration.

If you have the authority to sign in with a username and password, you can use the username-password flow (programmatic) to obtain a Microsoft Entra ID access token.

Authorization code flow (interactive)

There are two steps to acquire a Microsoft Entra ID access token using the authorization code flow.

  1. Request an authorization code, which launches a browser window and asks for Azure user login. The authorization code is returned after the user successfully logs in.
  2. Use the authorization code to acquire the Microsoft Entra ID access token. Depending on the approach that you use, a refresh token can also be returned at the same time and can be used to refresh the Microsoft Entra ID access token.

One approach to complete these two steps is to use your web browser and curl. To do this, you use your web browser to get the authorization code, and then you use the authorization code and curl to get the Microsoft Entra ID access token. This approach does not provide a refresh token.

Another approach is to use the MSAL Python library. To do this, you run a single script that uses your web browser to get the authorization code and then uses the authorization code to get both an access and refresh token.

Both of these approaches assume that you are already signed in to Azure. If you are not signed in, your web browser will prompt you to do so.

Get Microsoft Entra ID tokens by using a web browser and curl

  1. Gather the following information:

    Parameter Description
    Tenant ID The Directory (tenant) ID for the related application registered in Microsoft Entra ID in Configure an app in Azure portal.
    Client ID The Application (client) ID for the related application registered in Microsoft Entra ID.
    Redirect URI The appropriate Redirect URIs for the related application registered in Microsoft Entra ID (for example, http://localhost). The authentication responses are sent to this URI with the authorization code included.
  2. Get the authorization code by using your web browser to browse to the following URL. Replace the fields in the following URL example accordingly. Note that the URL must be sent as a single line; line breaks have been added to the following URL for readability. For more information, see Request an authorization code.

    https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id>
    &response_type=code
    &redirect_uri=<redirect-uri>
    &response_mode=query
    &scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default
    &state=<state>
    

    Replace:

    • <tenant-id> with the registered application’s tenant ID.
    • <client-id> with the registered application’s client ID.
    • <redirect-uri> with the registered application’s redirect URI. This URI must be in URL-encoded (percent-encoded) format. For example, http://localhost is http%3A%2F%2Flocalhost.
    • <state> with a random number or some encoded information. To help check for the integrity of information exchange, this state value should match the one that is in the returned URL later in this procedure.

    Do not change the value of the scope parameter. It represents the programmatic ID for Azure Databricks (2ff814a6-3304-4ab8-85cb-cd0e6f879c1d) along with the default scope (/.default, URL-encoded as %2f.default).

    For example:

    https://login.microsoftonline.com/a1bc2d34-5e67-8f89-01ab-c2345d6c78de/oauth2/v2.0/authorize?client_id=12a34b56-789c-0d12-e3fa-b456789c0123
    &response_type=code
    &redirect_uri=http%3A%2F%2Flocalhost
    &response_mode=query
    &scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default
    &state=12345
    
  3. Paste the URL as a single line into your web browser and, if prompted, sign in to Azure.

    HTTP request URL

  4. The authorization code is in the code field in the returned URL. Save the authorization code in a secure location. Also, check to make sure that the value of the state field matches the one that you provided earlier in this procedure.

    Authorization code URL

    The full returned URL will look something like this (with the full code field value shortened to 0.ASkAIj...RxgFhSAA here for brevity):

    http://localhost/?code=0.ASkAIj...RxgFhSAA&state=12345&session_state=c44574d5-38ba-4f93-b2a3-a830db8e8cdf
    
  5. Use the authorization code along with curl to get the Microsoft Entra ID access token.

    curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
    https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \
    -d 'client_id=<client-id>' \
    -d 'scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default' \
    -d 'code=<authorization-code>' \
    -d 'redirect_uri=<redirect-uri>' \
    -d 'grant_type=authorization_code' \
    -d 'state=<state>'
    

    Replace:

    • <tenant-id> with the registered application’s tenant ID.
    • <client-id> with the registered application’s client ID.
    • <authorization-code> with your authorization code.
    • <redirect-uri> with the registered application’s redirect URI. This URI must be in URL-encoded (percent-endoded) format. For example, http://localhost is http%3A%2F%2Flocalhost.
    • <state> with a random number or some encoded information. To help check for the integrity of information exchange, this state value should match the one that is in the response payload later in this procedure.

    Do not change the value of the scope parameter. It represents the programmatic ID for Azure Databricks (2ff814a6-3304-4ab8-85cb-cd0e6f879c1d) along with the default scope (/.default, URL-encoded as %2f.default).

    For example:

    curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
    https://login.microsoftonline.com/a1bc2d34-5e67-8f89-01ab-c2345d6c78de/oauth2/v2.0/token \
    -d 'client_id=12a34b56-789c-0d12-e3fa-b456789c0123' \
    -d 'scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default' \
    -d 'code=0.ASkAIj...RxgFhSAA' \
    -d 'redirect_uri=http%3A%2F%2Flocalhost' \
    -d 'grant_type=authorization_code' \
    -d 'state=12345'
    

    The Microsoft Entra ID token is in the access_token value within the result of the call. Be sure to check that the state value matches the one that you provided earlier in this procedure.

Get Microsoft Entra ID tokens by using the MSAL Python library

  1. Gather the following information:

    Parameter Description
    Tenant ID The Directory (tenant) ID for the related application registered in Microsoft Entra ID in Configure an app in Azure portal.
    Client ID The Application (client) ID for the related application registered in Microsoft Entra ID.

    This procedure assumes that you have set http://localhost as the Redirect URI for the related application registered in Microsoft Entra ID.

  2. Install the MSAL Python SDK on your local machine by running pip install msal.

  3. Save the following code as get-tokens.py on your local machine.

    # Given the client ID and tenant ID for an app registered in Azure,
    # provide a <ms-entra-id> access token and a refresh token.
    
    # If the caller is not already signed in to Azure, the caller's
    # web browser will prompt the caller to sign in first.
    
    # pip install msal
    from msal import PublicClientApplication
    import sys
    
    # You can hard-code the registered app's client ID and tenant ID here,
    # or you can provide them as command-line arguments to this script.
    client_id = '<client-id>'
    tenant_id = '<tenant-id>'
    
    # Do not modify this variable. It represents the programmatic ID for
    # Azure Databricks along with the default scope of '/.default'.
    scopes = [ '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default' ]
    
    # Check for too few or too many command-line arguments.
    if (len(sys.argv) > 1) and (len(sys.argv) != 3):
      print("Usage: get-tokens.py <client ID> <tenant ID>")
      exit(1)
    
    # If the registered app's client ID and tenant ID are provided as
    # command-line variables, set them here.
    if len(sys.argv) > 1:
      client_id = sys.argv[1]
      tenant_id = sys.argv[2]
    
    app = PublicClientApplication(
      client_id = client_id,
      authority = "https://login.microsoftonline.com/" + tenant_id
    )
    
    acquire_tokens_result = app.acquire_token_interactive(
      scopes = scopes
    )
    
    if 'error' in acquire_tokens_result:
      print("Error: " + acquire_tokens_result['error'])
      print("Description: " + acquire_tokens_result['error_description'])
    else:
      print("Access token:\n")
      print(acquire_tokens_result['access_token'])
      print("\nRefresh token:\n")
      print(acquire_tokens_result['refresh_token'])
    
  4. Do one of the following:

    • In the preceding code, replace <client-id> with the registered application’s client ID and <tenant-id> with the registered application’s tenant ID, and then run the script, for example python get-tokens.py.
    • Provide the registered application’s client ID and the registered application’s tenant ID when you run the script, for example python get-tokens.py 12a34b56-789c-0d12-e3fa-b456789c0123 a1bc2d34-5e67-8f89-01ab-c2345d6c78de.
  5. If your web browser prompts you, sign in to Azure.

  6. The Microsoft Entra ID access and refresh tokens are printed in the output.

Username-password flow (programmatic)

  1. If you have the authority to sign in with a username and password, gather the following information:

    Parameter Description
    Tenant ID The Directory (tenant) ID for the related application registered in Microsoft Entra ID in Configure an app in Azure portal.
    Client ID The Application (client) ID for the realted application registered in Microsoft Entra ID.
    Username and password The username (that is, the email address when you log in to Azure portal) and password of the user in the tenant.

    This procedure assumes that you have set http://localhost as the Redirect URI for the related application registered in Microsoft Entra ID.

  2. Install the MSAL Python SDK on your local machine by running pip install msal.

  3. Save the following code as get-tokens-for-user.py on your local machine.

    # Given the client ID and tenant ID for an app registered in Azure,
    # along with an Azure username and password,
    # provide a <ms-entra-id> access token and a refresh token.
    
    # If the caller is not already signed in to Azure, the caller's
    # web browser will prompt the caller to sign in first.
    
    # pip install msal
    from msal import PublicClientApplication
    import sys
    
    # You can hard-code the registered app's client ID and tenant ID here,
    # along with the Azure username and password,
    # or you can provide them as command-line arguments to this script.
    client_id = '<client-id>'
    tenant_id = '<tenant-id>'
    username = '<username>'
    password = '<password>'
    
    # Do not modify this variable. It represents the programmatic ID for
    # Azure Databricks along with the default scope of '/.default'.
    scope = [ '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default' ]
    
    # Check for too few or too many command-line arguments.
    if (len(sys.argv) > 1) and (len(sys.argv) != 5):
      print("Usage: get-tokens-for-user.py <client ID> <tenant ID> <username> <password>")
      exit(1)
    
    # If the registered app's client ID and tenant ID along with the
    # Azure username and password are provided as command-line variables,
    # set them here.
    if len(sys.argv) > 1:
      client_id = sys.argv[1]
      tenant_id = sys.argv[2]
      username = sys.argv[3]
      password = sys.argv[4]
    
    app = PublicClientApplication(
      client_id = client_id,
      authority = "https://login.microsoftonline.com/" + tenant_id
    )
    
    acquire_tokens_result = app.acquire_token_by_username_password(
      username = username,
      password = password,
      scopes = scope
    )
    
    if 'error' in acquire_tokens_result:
      print("Error: " + acquire_tokens_result['error'])
      print("Description: " + acquire_tokens_result['error_description'])
    else:
      print("Access token:\n")
      print(acquire_tokens_result['access_token'])
      print("\nRefresh token:\n")
      print(acquire_tokens_result['refresh_token'])
    
  4. Do one of the following:

    • In the preceding code, replace <client-id> with the registered application’s client ID, <tenant-id> with the registered application’s tenant ID, <username> with the username, and <password> with the password, and then run the script, for example python get-tokens-for-user.py.
    • Provide the registered application’s client ID, the registered application’s tenant ID, the username, and the password when you run the script, for example python get-tokens-for-user.py 12a34b56-789c-0d12-e3fa-b456789c0123 a1bc2d34-5e67-8f89-01ab-c2345d6c78de someone@example.com "MyPa55w&rd!". If a command-line argument contains special characters, you should surround it with quotes.
  5. The Microsoft Entra ID access and refresh tokens are printed to your terminal.

Use a Microsoft Entra ID access token to access the Databricks REST API

This section describes how to use a Microsoft Entra ID access token to call the Databricks REST API. In the following examples, replace <access-token> with the Microsoft Entra ID access token and <databricks-instance> with the per-workspace URL of your Azure Databricks deployment.

Python example

This example shows how to list the clusters in an Azure Databricks workspace.

import requests
import json

databricks_instance = '<databricks-instance>'
api_version = '/api/2.0'
api_command = '/clusters/list'
url = f"https://{databricks_instance}{api_version}{api_command}"
access_token = '<access-token>'

response = requests.get(
  url = url,
  headers = { 'Authorization': "Bearer " + access_token}
)

print(json.dumps(json.loads(response.text), indent = 2))

Note

If you are a non-admin user and want to log in as an admin user, you must provide the X-Databricks-Azure-Workspace-Resource-Id header in addition to the 'Authorization' : 'Bearer ' header and you must be in a Contributor or Owner role on the workspace resource in Azure. You construct the X-Databricks-Azure-Workspace-Resource-Id value as follows:

# ...

subscription = '<azure-subscription-id>'
resource_group = '<azure-resource-group-name>'
workspace = '<databricks-workspace-name-in-azure>'

db_resource_id = '/subscriptions/%s/resourcegroups/%s/providers/microsoft.databricks/workspaces/%s' % (
  subscription,
  resource_group,
  workspace
)

# ...

  headers = {
    'Authorization': "Bearer " + access_token,
    'X-Databricks-Azure-Workspace-Resource-Id': db_resource_id
  }

# ...

To get the subscription, resource, and workspace information in Azure, see Open resources. To open the target resource, you can search on the Azure Databricks service type and any other information in Azure that you know about the target Azure Databricks workspace.

curl example

curl -X GET \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-token>' \
https://<databricks-instance>/api/2.0/clusters/list

Refresh a Microsoft Entra ID access token

If you get a refresh token along with your Microsoft Entra ID access token, you can use the refresh token to obtain a new token. By default, the lifetime of Microsoft Entra ID access tokens is a random time period between 60 and 90 minutes (75 minutes on average). You can configure the lifetime of Microsoft Entra ID access tokens by using the methods in Configurable token lifetimes in Microsoft Entra ID (formerly Azure Active Directory).

The following example shows how to use the MSAL Python library along with a refresh token to obtain a new token.

  1. Save the following code as refresh-tokens.py on your local machine.

    # Given the client ID and tenant ID for an app registered in Azure,
    # along with a refresh token, provide a new <ms-entra-id> access token and
    # refresh token.
    
    # If the caller is not already signed in to Azure, the caller's
    # web browser will prompt the caller to sign in first.
    
    # pip install msal
    from msal import PublicClientApplication
    import sys
    
    # You can hard-code the registered app's client ID, tenant ID,
    # and refresh token here, or you can provide them as command-line
    # arguments to this script.
    client_id = '<client-id>'
    tenant_id = '<refresh-token'
    refresh_token = '<refresh-token>'
    
    # Do not modify this variable. It represents the programmatic ID for
    # Azure Databricks along with the default scope of '.default'.
    scope = [ '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default' ]
    
    # Check for too few or too many command-line arguments.
    if (len(sys.argv) > 1) and (len(sys.argv) != 4):
      print("Usage: refresh-tokens.py <client ID> <tenant ID> <refresh token>")
      exit(1)
    
    # If the registered app's client ID, tenant ID, and refresh token are
    # provided as command-line variables, set them here.
    if len(sys.argv) > 1:
      client_id = sys.argv[1]
      tenant_id = sys.argv[2]
      refresh_token = sys.argv[3]
    
    app = PublicClientApplication(
      client_id = client_id,
      authority = "https://login.microsoftonline.com/" + tenant_id
    )
    
    acquire_tokens_result = app.acquire_token_by_refresh_token(
      refresh_token = refresh_token,
      scopes = scope
    )
    
    if 'error' in acquire_tokens_result:
      print("Error: " + acquire_tokens_result['error'])
      print("Description: " + acquire_tokens_result['error_description'])
    else:
      print("\nNew access token:\n")
      print(acquire_tokens_result['access_token'])
      print("\nNew refresh token:\n")
      print(acquire_tokens_result['refresh_token'])
    
  2. Do one of the following:

    • In the preceding code, replace <client-id> with the registered application’s client ID, <tenant-id> with the registered application’s tenant ID, and <refresh-token> with the refresh token, and then run the script, for example python get-tokens-for-user.py.
    • Provide the registered application’s client ID, the registered application’s tenant ID, and the refresh token when you run the script, for example python refresh-tokens.py 12a34b56-789c-0d12-e3fa-b456789c0123 a1bc2d34-5e67-8f89-01ab-c2345d6c78de "0.ASkAIj...huE84ALg". If a command-line argument contains special characters, you should surround it in quotes.
  3. The new Microsoft Entra ID access and refresh tokens are printed to your terminal.