ADAL for Python is a legacy library that enabled Python applications to authenticate to Azure Active Directory (AAD) to access AAD-protected web resources. It has been replaced by the Microsoft Authentication Library (MSAL) for Python, which offers broader functionality and support for newer authentication protocols and features. ADAL Python will no longer receive new feature improvements or bug fixes. The current version is 1.2.7.
Install & Compatibility
Where this runs
tested against v1.2.7 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.925 runs
installs and imports cleanly · install 0.0s · import 0.801s · 39.2MB
glibcpy 3.10–3.925 runs
installs and imports cleanly · install 3.2s · import 0.716s · 40MB
38MB installed
● package 38MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
AuthenticationContext
✓ from adal import AuthenticationContext
AdalError
✓ from adal import AdalError
This quickstart demonstrates how to acquire an access token using the client credentials flow, where an application authenticates itself using a client ID and client secret to access a protected resource like Microsoft Graph. Ensure you have registered an application in Azure AD and granted it appropriate permissions.
import os
import adal
# Set these environment variables or replace directly for testing
TENANT_ID = os.environ.get('AZURE_TENANT_ID', 'your_tenant_id_here')
CLIENT_ID = os.environ.get('AZURE_CLIENT_ID', 'your_client_id_here')
CLIENT_SECRET = os.environ.get('AZURE_CLIENT_SECRET', 'your_client_secret_here')
RESOURCE = os.environ.get('AZURE_RESOURCE', 'https://graph.microsoft.com') # Example: Microsoft Graph URL
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
try:
# Initialize AuthenticationContext, explicitly setting api_version=None is recommended
context = adal.AuthenticationContext(
AUTHORITY,
validate_authority=True,
api_version=None
)
# Acquire a token using the client credentials flow
# This flow is for daemon/service applications that authenticate as themselves
token_response = context.acquire_token_with_client_credentials(
RESOURCE,
CLIENT_ID,
CLIENT_SECRET
)
access_token = token_response.get('accessToken')
if access_token:
print("Successfully acquired access token.")
print(f"Access Token (first 20 chars): {access_token[:20]}...")
# You can now use the access_token to call the protected resource
# Example: import requests; headers = {'Authorization': 'Bearer ' + access_token}
# response = requests.get(f'{RESOURCE}/v1.0/users', headers=headers)
# print(response.json())
else:
print("Failed to acquire access token.")
print(token_response)
except adal.AdalError as e:
print(f"ADAL Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
Debug
Known issues
breakingADAL for Python is deprecated and will not receive new features or bug fixes. All new development should use MSAL for Python (Microsoft Authentication Library). Existing applications relying on ADAL Python will continue to work, but migration to MSAL is strongly recommended.fixMigrate your application to use MSAL Python. Install with `pip install msal`. Refer to the official 'ADAL to MSAL migration guide for Python' for detailed steps and API changes.
affects: All versions (since MSAL's release)
breakingWhen migrating from ADAL to MSAL, note a fundamental change in how resources are specified. ADAL uses 'resources' (e.g., `https://graph.microsoft.com`), while MSAL uses 'scopes' (a list of strings).fixConvert ADAL `resource` values to MSAL `scope` lists. For a v1.0 endpoint resource, append `/.default` to form the scope, e.g., `https://graph.microsoft.com` becomes `['https://graph.microsoft.com/.default']`.
affects: All versions, when migrating to MSAL.
deprecatedThe `api_version` parameter in `AuthenticationContext` implicitly defaulted to '1.0' in older versions. In ADAL Python 1.0.0 and later, the default value became `None`. Explicitly setting `api_version=None` is recommended to avoid deprecation warnings and ensure consistent behavior.fixWhen creating an `AuthenticationContext` instance, always set `api_version=None`: `context = adal.AuthenticationContext(..., api_version=None)`.
affects: 1.0.0 and later
gotchaVersions of ADAL Python prior to 1.2.6 could incorrectly pick up the latest PyJWT 2.x, leading to compatibility issues.fixUpgrade ADAL to version 1.2.6 or higher to ensure compatibility with both PyJWT 1.x and 2.x.
affects: < 1.2.6
gotchaVersions of ADAL Python prior to 1.2.5 might encounter an 'InvalidScope' error when using the username-password flow with federated user accounts during tenant migration.fixUpgrade ADAL to version 1.2.5 or higher to fix the 'InvalidScope' error in specific username-password flow scenarios.
affects: < 1.2.5
breakingADAL operations fail with AADSTS900023 if an invalid tenant identifier is provided. The tenant identifier must be a valid GUID, domain name, or 'common', 'organizations', 'consumers'.fixEnsure the tenant identifier (e.g., in the authority URL provided to `adal.AuthenticationContext`) is a valid GUID, a verified domain name for your Azure AD tenant, or one of the common endpoints ('common', 'organizations', 'consumers'). affects: All versions
gotchaADAL operations fail with `AADSTS900023: Specified tenant identifier ... is neither a valid DNS name, nor a valid external domain` when the provided tenant ID in the authority URL (e.g., `https://login.microsoftonline.com/{tenant_id}`) is incorrect or malformed.fixEnsure the tenant ID (GUID or domain name) used in the authority URL is correct and valid for your Azure AD tenant. Double-check for typos or incorrect values in the authority URL.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'adal'
The 'adal' library is not installed in the Python environment.
fixInstall the 'adal' library using pip: 'pip install adal'.
ImportError: cannot import name 'AuthenticationContext' from 'adal'
The 'adal' library is not installed or the import statement is incorrect.
fixEnsure 'adal' is installed and use the correct import statement: 'from adal import AuthenticationContext'.
AttributeError: module 'adal' has no attribute 'acquire_token_with_client_credentials'
The 'acquire_token_with_client_credentials' method is not directly available in the 'adal' module; it is a method of the 'AuthenticationContext' class.
fixCreate an instance of 'AuthenticationContext' and call 'acquire_token_with_client_credentials' on it: 'context = AuthenticationContext(authority_url); token = context.acquire_token_with_client_credentials(resource, client_id, client_secret)'.
adal.adal_error.AdalError: Get Token request returned http error: 400 and server response: {"error":"invalid_client","error_description":"AADSTS7000215: Invalid client secret provided."}
The client secret provided is incorrect or invalid.
fixVerify and use the correct client secret associated with your Azure AD application.
adal.adal_error.AdalError: Get Token request returned http error: 401 and server response: {"error":"unauthorized_client","error_description":"AADSTS700016: Application with identifier 'client_id' was not found in the directory 'tenant_id'."}
The client ID provided does not match any registered application in the specified Azure AD tenant.
fixEnsure the correct client ID is used and that the application is registered in the specified Azure AD tenant.
Audit
Dependencies
requestsrequiredUsed for HTTP requests, often for API calls after token acquisition.
PyJWTrequiredUsed for JWT handling; older ADAL versions had compatibility issues with PyJWT 2.x.