Microsoft Authentication Library for Python enabling OAuth2/OIDC authentication with Microsoft identity platform
—
Public client applications are designed for desktop and mobile applications where the client cannot securely store credentials. MSAL Python's PublicClientApplication supports interactive authentication through web browsers, device code flow for browserless environments, and optional broker integration for enhanced security.
Creates a public client application instance with optional broker support for enhanced security through device identity and single sign-on capabilities.
class PublicClientApplication(ClientApplication):
def __init__(
self,
client_id: str,
client_credential=None, # Must remain None for public clients
*,
enable_broker_on_windows=None,
enable_broker_on_mac=None,
enable_broker_on_linux=None,
enable_broker_on_wsl=None,
authority=None,
validate_authority=True,
token_cache=None,
http_client=None,
verify=True,
proxies=None,
timeout=None,
client_claims=None,
app_name=None,
app_version=None,
client_capabilities=None,
exclude_scopes=None,
http_cache=None,
instance_discovery=None,
allow_broker=None,
enable_pii_log=None,
oidc_authority=None,
**kwargs
):
"""
Create a public client application.
Parameters:
- client_id: Your app's client ID from Azure portal
- enable_broker_on_windows: Enable broker on Windows 10+ (requires redirect URI)
- enable_broker_on_mac: Enable broker on macOS with Company Portal
- enable_broker_on_linux: Enable broker on Linux
- enable_broker_on_wsl: Enable broker on Windows Subsystem for Linux
- authority: Authority URL (default: https://login.microsoftonline.com/common)
- token_cache: Custom token cache instance
- http_client: Custom HTTP client
- proxies: HTTP proxy configuration
- timeout: HTTP timeout in seconds
"""Usage example:
import msal
# Basic public client
app = msal.PublicClientApplication(
client_id="12345678-1234-1234-1234-123456789012",
authority="https://login.microsoftonline.com/common"
)
# With broker support (requires appropriate redirect URI registration)
app_with_broker = msal.PublicClientApplication(
client_id="12345678-1234-1234-1234-123456789012",
authority="https://login.microsoftonline.com/your-tenant-id",
enable_broker_on_windows=True,
enable_broker_on_mac=True
)Performs interactive authentication by opening a web browser for user sign-in. Supports various prompt behaviors, login hints, and additional consent scopes.
def acquire_token_interactive(
self,
scopes: list,
prompt=None,
login_hint=None,
domain_hint=None,
claims_challenge=None,
timeout=None,
port=None,
extra_scopes_to_consent=None,
max_age=None,
parent_window_handle=None,
on_before_launching_ui=None,
auth_scheme=None,
**kwargs
):
"""
Acquire token interactively via web browser.
Parameters:
- scopes: List of scopes to request (e.g., ["User.Read", "Mail.Send"])
- prompt: Prompt behavior (msal.Prompt.NONE, LOGIN, CONSENT, SELECT_ACCOUNT)
- login_hint: Email address to pre-populate sign-in form
- domain_hint: Domain hint to skip domain selection
- claims_challenge: Additional claims from resource provider
- timeout: Browser interaction timeout in seconds
- port: Local server port for auth response (default: random)
- extra_scopes_to_consent: Additional scopes for upfront consent
- max_age: Maximum authentication age in seconds
- parent_window_handle: Handle to parent window (Windows only)
- on_before_launching_ui: Callback before launching browser
- auth_scheme: Authentication scheme (e.g., PopAuthScheme for PoP tokens)
Returns:
Dictionary with 'access_token' on success, 'error' on failure
"""Usage example:
import msal
app = msal.PublicClientApplication(
client_id="your-client-id",
authority="https://login.microsoftonline.com/common"
)
# Basic interactive authentication
result = app.acquire_token_interactive(
scopes=["User.Read", "Mail.Read"]
)
# With specific prompt and login hint
result = app.acquire_token_interactive(
scopes=["User.Read"],
prompt=msal.Prompt.SELECT_ACCOUNT,
login_hint="user@example.com",
timeout=120
)
if "access_token" in result:
print("Authentication successful!")
access_token = result["access_token"]
expires_in = result["expires_in"]
else:
print(f"Error: {result.get('error')}")
print(f"Description: {result.get('error_description')}")Initiates and completes device code authentication flow for devices without web browsers or limited input capabilities. Users authenticate on a separate device using a provided code.
def initiate_device_flow(
self,
scopes=None,
**kwargs
):
"""
Initiate device code flow.
Parameters:
- scopes: List of scopes to request
Returns:
Dictionary containing device_code, user_code, verification_uri,
verification_uri_complete, expires_in, interval, and message
"""
def acquire_token_by_device_flow(
self,
flow: dict,
claims_challenge=None,
**kwargs
):
"""
Complete device code flow with polling.
Parameters:
- flow: Flow dictionary from initiate_device_flow()
- claims_challenge: Additional claims from resource provider
Returns:
Dictionary with 'access_token' on success, 'error' on failure
"""Usage example:
import msal
import time
app = msal.PublicClientApplication(
client_id="your-client-id",
authority="https://login.microsoftonline.com/common"
)
# Initiate device flow
flow = app.initiate_device_flow(scopes=["User.Read"])
if "user_code" not in flow:
raise ValueError(f"Failed to create device flow: {flow.get('error_description')}")
# Display instructions to user
print(flow["message"])
# Poll for completion
result = app.acquire_token_by_device_flow(flow)
if "access_token" in result:
print("Device authentication successful!")
access_token = result["access_token"]
else:
print(f"Device authentication failed: {result.get('error_description')}")When broker is enabled, authentication goes through the platform's authentication broker (e.g., Web Account Manager on Windows, Company Portal on macOS) for enhanced security and single sign-on capabilities.
Required redirect URIs for broker support:
ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_idmsauth.com.msauth.unsignedapp://authhttp://localhostUsage considerations:
# Broker-enabled application
app = msal.PublicClientApplication(
client_id="your-client-id",
authority="https://login.microsoftonline.com/your-tenant-id",
enable_broker_on_windows=True,
enable_broker_on_mac=True,
enable_broker_on_linux=True
)
# Interactive auth will use broker when available
result = app.acquire_token_interactive(scopes=["User.Read"])Common error scenarios and handling patterns:
result = app.acquire_token_interactive(scopes=["User.Read"])
if "access_token" in result:
# Success
access_token = result["access_token"]
expires_in = result["expires_in"]
token_type = result.get("token_type", "Bearer")
elif result.get("error") == "access_denied":
# User cancelled or denied consent
print("User cancelled authentication")
elif result.get("error") == "invalid_scope":
# Invalid or unauthorized scope requested
print(f"Invalid scope: {result.get('error_description')}")
elif result.get("error") == "interaction_required":
# Silent authentication failed, interaction needed
print("Interactive authentication required")
else:
# Other error
print(f"Authentication failed: {result.get('error_description')}")Install with Tessl CLI
npx tessl i tessl/pypi-msal