{"id":6854,"library":"requests-ntlm3","title":"Requests NTLMv2 Authentication","description":"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.","status":"active","version":"6.1.3b1","language":"en","source_language":"en","source_url":"https://github.com/mchampanis/requests-ntlm3","tags":["requests","ntlm","authentication","proxy","windows","http","security"],"install":[{"cmd":"pip install requests-ntlm3","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core HTTP library dependency.","package":"requests","optional":false},{"reason":"Provides the underlying SPNEGO/NTLM authentication mechanism.","package":"pyspnego","optional":false}],"imports":[{"note":"The library is `requests-ntlm3` (with a dash), but the import path uses `requests_ntlm3` (with an underscore) to distinguish it from the older `requests-ntlm`.","wrong":"from requests_ntlm import HttpNtlmAuth","symbol":"HttpNtlmAuth","correct":"from requests_ntlm3 import HttpNtlmAuth"}],"quickstart":{"code":"import requests\nimport os\nfrom requests_ntlm3 import HttpNtlmAuth\n\n# --- NTLM Server Authentication Example ---\n\nNTLM_USERNAME = os.environ.get('NTLM_SERVER_USERNAME', 'DOMAIN\\\\user')\nNTLM_PASSWORD = os.environ.get('NTLM_SERVER_PASSWORD', 'your_password')\nNTLM_SERVER_URL = os.environ.get('NTLM_SERVER_URL', 'http://localhost/protected')\n\nif NTLM_USERNAME and NTLM_PASSWORD and NTLM_SERVER_URL != 'http://localhost/protected':\n    try:\n        print(f\"Attempting NTLM server auth to {NTLM_SERVER_URL} with user {NTLM_USERNAME.split('\\\\')[-1]}...\")\n        response = requests.get(\n            NTLM_SERVER_URL,\n            auth=HttpNtlmAuth(NTLM_USERNAME, NTLM_PASSWORD)\n        )\n        response.raise_for_status()\n        print(f\"NTLM Server Auth Success: Status {response.status_code}, Length {len(response.text)}.\")\n    except requests.exceptions.RequestException as e:\n        print(f\"NTLM Server Auth Failed: {e}\")\nelse:\n    print(\"Skipping NTLM server auth example: Set NTLM_SERVER_USERNAME, NTLM_SERVER_PASSWORD, NTLM_SERVER_URL env vars.\")\n\n# --- NTLM Proxy Authentication Example ---\n\nPROXY_USERNAME = os.environ.get('NTLM_PROXY_USERNAME', 'DOMAIN\\\\proxyuser')\nPROXY_PASSWORD = os.environ.get('NTLM_PROXY_PASSWORD', 'proxy_password')\nPROXY_URL = os.environ.get('NTLM_PROXY_URL', 'http://your_proxy_server:8080')\nTARGET_URL_VIA_PROXY = os.environ.get('TARGET_URL_VIA_PROXY', 'http://www.example.com')\n\nif PROXY_USERNAME and PROXY_PASSWORD and PROXY_URL != 'http://your_proxy_server:8080':\n    proxies = {\n        \"http\": PROXY_URL,\n        \"https\": PROXY_URL # Use http for https proxy auth as well for NTLM proxies\n    }\n    try:\n        print(f\"Attempting NTLM proxy auth via {PROXY_URL} to {TARGET_URL_VIA_PROXY} with user {PROXY_USERNAME.split('\\\\')[-1]}...\")\n        response = requests.get(\n            TARGET_URL_VIA_PROXY,\n            proxies=proxies,\n            auth=HttpNtlmAuth(PROXY_USERNAME, PROXY_PASSWORD, ntlm_proxy_auth=True)\n        )\n        response.raise_for_status()\n        print(f\"NTLM Proxy Auth Success: Status {response.status_code}, Length {len(response.text)}.\")\n    except requests.exceptions.RequestException as e:\n        print(f\"NTLM Proxy Auth Failed: {e}\")\nelse:\n    print(\"Skipping NTLM proxy auth example: Set NTLM_PROXY_USERNAME, NTLM_PROXY_PASSWORD, NTLM_PROXY_URL, TARGET_URL_VIA_PROXY env vars.\")","lang":"python","description":"Demonstrates both NTLM server authentication and NTLM proxy authentication. For proxy authentication, ensure `ntlm_proxy_auth=True` is passed to `HttpNtlmAuth`. Environment variables are used for credentials and URLs to keep the example runnable without hardcoding sensitive data. Remember to replace placeholder values with your actual NTLM credentials and URLs."},"warnings":[{"fix":"If migrating from `requests-ntlm`, update your `pip install` command to `requests-ntlm3` and change your import statement from `from requests_ntlm import HttpNtlmAuth` to `from requests_ntlm3 import HttpNtlmAuth`.","message":"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`.","severity":"breaking","affected_versions":"All versions"},{"fix":"When authenticating against an NTLM proxy, initialize `HttpNtlmAuth(username, password, ntlm_proxy_auth=True)`. Example: `requests.get(url, proxies=proxies, auth=HttpNtlmAuth(user, pw, ntlm_proxy_auth=True))`.","message":"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`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Consult your IT administrator or NTLM server configuration for the exact required username format. Try both `DOMAIN\\username` and `username@domain.com` if unsure.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Configure your `proxies` dictionary like `{\"http\": \"http://proxy:port\", \"https\": \"http://proxy:port\"}` when the proxy itself requires NTLM and serves both HTTP and HTTPS traffic.","message":"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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}