Requests NTLMv2 Authentication
A modern `requests` authentication handler for NTLM authentication, utilizing `pyspnego` for robust NTLMv1/v2 support, including both server and proxy authentication. This library is distinct from `requests-ntlm` and is compatible with Python 3 and modern NTLM implementations. It is actively maintained with a regular release cadence as needed for bug fixes and updates.
Warnings
- breaking This library is `requests-ntlm3`, which is a distinct project from `requests-ntlm`. They use different underlying NTLM implementations (`pyspnego` vs `python-ntlm`) and have different import paths. Ensure you are importing `from requests_ntlm3 import HttpNtlmAuth`.
- gotcha NTLM authentication against a proxy server requires setting `ntlm_proxy_auth=True` in the `HttpNtlmAuth` constructor. By default, it performs server authentication (`ntlm_proxy_auth=False`).
- gotcha The username format for NTLM authentication is crucial and varies. Common formats are `DOMAIN\username` or `username@domain.com`. Incorrect formatting will lead to authentication failures.
- gotcha When using an NTLM proxy to access an `https` destination, the proxy dictionary should typically still specify the proxy's URL with an `http://` scheme, even for the `https` key. The NTLM authentication happens over the non-encrypted proxy connection.
Install
-
pip install requests-ntlm3
Imports
- HttpNtlmAuth
from requests_ntlm import HttpNtlmAuth
from requests_ntlm3 import HttpNtlmAuth
Quickstart
import requests
import os
from requests_ntlm3 import HttpNtlmAuth
# --- NTLM Server Authentication Example ---
NTLM_USERNAME = os.environ.get('NTLM_SERVER_USERNAME', 'DOMAIN\\user')
NTLM_PASSWORD = os.environ.get('NTLM_SERVER_PASSWORD', 'your_password')
NTLM_SERVER_URL = os.environ.get('NTLM_SERVER_URL', 'http://localhost/protected')
if NTLM_USERNAME and NTLM_PASSWORD and NTLM_SERVER_URL != 'http://localhost/protected':
try:
print(f"Attempting NTLM server auth to {NTLM_SERVER_URL} with user {NTLM_USERNAME.split('\\')[-1]}...")
response = requests.get(
NTLM_SERVER_URL,
auth=HttpNtlmAuth(NTLM_USERNAME, NTLM_PASSWORD)
)
response.raise_for_status()
print(f"NTLM Server Auth Success: Status {response.status_code}, Length {len(response.text)}.")
except requests.exceptions.RequestException as e:
print(f"NTLM Server Auth Failed: {e}")
else:
print("Skipping NTLM server auth example: Set NTLM_SERVER_USERNAME, NTLM_SERVER_PASSWORD, NTLM_SERVER_URL env vars.")
# --- NTLM Proxy Authentication Example ---
PROXY_USERNAME = os.environ.get('NTLM_PROXY_USERNAME', 'DOMAIN\\proxyuser')
PROXY_PASSWORD = os.environ.get('NTLM_PROXY_PASSWORD', 'proxy_password')
PROXY_URL = os.environ.get('NTLM_PROXY_URL', 'http://your_proxy_server:8080')
TARGET_URL_VIA_PROXY = os.environ.get('TARGET_URL_VIA_PROXY', 'http://www.example.com')
if PROXY_USERNAME and PROXY_PASSWORD and PROXY_URL != 'http://your_proxy_server:8080':
proxies = {
"http": PROXY_URL,
"https": PROXY_URL # Use http for https proxy auth as well for NTLM proxies
}
try:
print(f"Attempting NTLM proxy auth via {PROXY_URL} to {TARGET_URL_VIA_PROXY} with user {PROXY_USERNAME.split('\\')[-1]}...")
response = requests.get(
TARGET_URL_VIA_PROXY,
proxies=proxies,
auth=HttpNtlmAuth(PROXY_USERNAME, PROXY_PASSWORD, ntlm_proxy_auth=True)
)
response.raise_for_status()
print(f"NTLM Proxy Auth Success: Status {response.status_code}, Length {len(response.text)}.")
except requests.exceptions.RequestException as e:
print(f"NTLM Proxy Auth Failed: {e}")
else:
print("Skipping NTLM proxy auth example: Set NTLM_PROXY_USERNAME, NTLM_PROXY_PASSWORD, NTLM_PROXY_URL, TARGET_URL_VIA_PROXY env vars.")