{"id":601,"library":"adal","title":"Azure Active Directory Authentication Library (ADAL) for Python","description":"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.","status":"deprecated","version":"1.2.7","language":"python","source_language":"en","source_url":"https://github.com/AzureAD/azure-activedirectory-library-for-python","tags":["authentication","azure","active-directory","microsoft","oauth"],"install":[{"cmd":"pip install adal","lang":"bash","label":"Install ADAL Python"}],"dependencies":[{"reason":"Used for HTTP requests, often for API calls after token acquisition.","package":"requests","optional":false},{"reason":"Used for JWT handling; older ADAL versions had compatibility issues with PyJWT 2.x.","package":"PyJWT","optional":false}],"imports":[{"symbol":"AuthenticationContext","correct":"from adal import AuthenticationContext"},{"symbol":"AdalError","correct":"from adal import AdalError"}],"quickstart":{"code":"import os\nimport adal\n\n# Set these environment variables or replace directly for testing\nTENANT_ID = os.environ.get('AZURE_TENANT_ID', 'your_tenant_id_here')\nCLIENT_ID = os.environ.get('AZURE_CLIENT_ID', 'your_client_id_here')\nCLIENT_SECRET = os.environ.get('AZURE_CLIENT_SECRET', 'your_client_secret_here')\nRESOURCE = os.environ.get('AZURE_RESOURCE', 'https://graph.microsoft.com') # Example: Microsoft Graph URL\n\nAUTHORITY = f\"https://login.microsoftonline.com/{TENANT_ID}\"\n\ntry:\n    # Initialize AuthenticationContext, explicitly setting api_version=None is recommended\n    context = adal.AuthenticationContext(\n        AUTHORITY,\n        validate_authority=True,\n        api_version=None\n    )\n\n    # Acquire a token using the client credentials flow\n    # This flow is for daemon/service applications that authenticate as themselves\n    token_response = context.acquire_token_with_client_credentials(\n        RESOURCE,\n        CLIENT_ID,\n        CLIENT_SECRET\n    )\n\n    access_token = token_response.get('accessToken')\n\n    if access_token:\n        print(\"Successfully acquired access token.\")\n        print(f\"Access Token (first 20 chars): {access_token[:20]}...\")\n        # You can now use the access_token to call the protected resource\n        # Example: import requests; headers = {'Authorization': 'Bearer ' + access_token}\n        # response = requests.get(f'{RESOURCE}/v1.0/users', headers=headers)\n        # print(response.json())\n    else:\n        print(\"Failed to acquire access token.\")\n        print(token_response)\n\nexcept adal.AdalError as e:\n    print(f\"ADAL Error: {e}\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")\n","lang":"python","description":"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."},"warnings":[{"fix":"Migrate 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.","message":"ADAL 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.","severity":"breaking","affected_versions":"All versions (since MSAL's release)"},{"fix":"Convert 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']`.","message":"When 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).","severity":"breaking","affected_versions":"All versions, when migrating to MSAL."},{"fix":"When creating an `AuthenticationContext` instance, always set `api_version=None`: `context = adal.AuthenticationContext(..., api_version=None)`.","message":"The `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.","severity":"deprecated","affected_versions":"1.0.0 and later"},{"fix":"Upgrade ADAL to version 1.2.6 or higher to ensure compatibility with both PyJWT 1.x and 2.x.","message":"Versions of ADAL Python prior to 1.2.6 could incorrectly pick up the latest PyJWT 2.x, leading to compatibility issues.","severity":"gotcha","affected_versions":"< 1.2.6"},{"fix":"Upgrade ADAL to version 1.2.5 or higher to fix the 'InvalidScope' error in specific username-password flow scenarios.","message":"Versions 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.","severity":"gotcha","affected_versions":"< 1.2.5"},{"fix":"Ensure 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').","message":"ADAL 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'.","severity":"breaking","affected_versions":"All versions"},{"fix":"Ensure 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.","message":"ADAL 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T16:27:01.577Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the 'adal' library using pip: 'pip install adal'.","cause":"The 'adal' library is not installed in the Python environment.","error":"ModuleNotFoundError: No module named 'adal'"},{"fix":"Ensure 'adal' is installed and use the correct import statement: 'from adal import AuthenticationContext'.","cause":"The 'adal' library is not installed or the import statement is incorrect.","error":"ImportError: cannot import name 'AuthenticationContext' from 'adal'"},{"fix":"Create 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)'.","cause":"The 'acquire_token_with_client_credentials' method is not directly available in the 'adal' module; it is a method of the 'AuthenticationContext' class.","error":"AttributeError: module 'adal' has no attribute 'acquire_token_with_client_credentials'"},{"fix":"Verify and use the correct client secret associated with your Azure AD application.","cause":"The client secret provided is incorrect or invalid.","error":"adal.adal_error.AdalError: Get Token request returned http error: 400 and server response: {\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided.\"}"},{"fix":"Ensure the correct client ID is used and that the application is registered in the specified Azure AD tenant.","cause":"The client ID provided does not match any registered application in the specified Azure AD tenant.","error":"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'.\"}"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":"1.2.7","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.71,"mem_mb":13.9,"disk_size":"39.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.77,"mem_mb":13.8,"disk_size":"38.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.3,"import_time_s":0.52,"mem_mb":13.9,"disk_size":"40M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.56,"mem_mb":13.8,"disk_size":"38M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.92,"mem_mb":14.9,"disk_size":"41.7M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.02,"mem_mb":14.9,"disk_size":"40.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.1,"import_time_s":0.78,"mem_mb":14.9,"disk_size":"42M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.77,"mem_mb":14.9,"disk_size":"41M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.8,"mem_mb":15.5,"disk_size":"33.3M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.87,"mem_mb":15.5,"disk_size":"32.3M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.7,"import_time_s":0.8,"mem_mb":15.5,"disk_size":"34M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.93,"mem_mb":15.5,"disk_size":"33M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.81,"mem_mb":15.8,"disk_size":"33.1M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.83,"mem_mb":15.8,"disk_size":"31.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.7,"import_time_s":0.76,"mem_mb":15.8,"disk_size":"34M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.85,"mem_mb":15.8,"disk_size":"32M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.67,"mem_mb":13.5,"disk_size":"39.1M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.7,"mem_mb":13.6,"disk_size":"38.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.9,"import_time_s":0.67,"mem_mb":13.5,"disk_size":"40M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":13.6,"disk_size":"38M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}