When working with Python scripts in corporate environments, one of the most frustrating roadblocks is NTLM authentication through proxy servers. Unlike some other languages, Python's native libraries don't provide seamless NTLM support, resulting in persistent 407 Proxy Authentication Required errors.
While IIS with Application Request Routing seems like a viable solution for forwarding requests, it has limitations with credential passthrough. The core issue is that ARR doesn't automatically forward the current user's NTLM credentials from the originating Python script to the corporate proxy.
After testing multiple approaches, I found that setting up Squid as a local proxy with NTLM authentication support works reliably. Here's how to implement it:
# Install Squid on Windows
choco install squid
# Configure squid.conf
http_port 3128
cache_peer corporate.proxy.com parent 8080 0 default no-query login=PASSTHRU
never_direct allow all
For simpler cases, you can use the requests-ntlm library as a wrapper:
import requests
from requests_ntlm import HttpNtlmAuth
session = requests.Session()
session.auth = HttpNtlmAuth('DOMAIN\\username','password')
response = session.get('https://target-api.com', proxies={'https': 'corporate.proxy.com:8080'})
For true credential passthrough without hardcoding passwords, you'll need to configure Kerberos delegation. This requires Active Directory configuration:
# In PowerShell (run as admin)
Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy -Value 1
Remember that each NTLM authentication adds significant overhead. Consider implementing connection pooling:
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
session.mount('https://', HTTPAdapter(
max_retries=Retry(
total=3,
backoff_factor=0.5,
status_forcelist=[407]
)
))
When working with Python scripts in corporate environments, one of the most frustrating roadblocks is dealing with NTLM-authenticated proxies. The standard Python HTTP libraries (requests, urllib) lack native NTLM support, leading to persistent 407 Proxy Authentication Required errors.
Application Request Routing (ARR) in IIS can serve as an effective local proxy that handles the NTLM handshake while forwarding requests to your corporate proxy. This approach delegates the authentication complexity to IIS while keeping your Python code simple.
First, ensure you have IIS with ARR installed:
# PowerShell installation Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServer Enable-WindowsOptionalFeature -Online -FeatureName IIS-ApplicationDevelopment Install-WindowsFeature Web-Proxy -IncludeManagementTools
Create a new Server Farm in ARR with these settings:
<applicationRequestRouting> <serverFarms> <serverFarm name="CorporateProxy"> <server address="corporate.proxy.com" port="8080" /> </serverFarm> </serverFarms> <proxy enabled="true" /> </applicationRequestRouting>
Now your Python script can simply point to the local proxy (no NTLM handling required):
import requests proxies = { 'http': 'http://localhost:8080', 'https': 'http://localhost:8080' } response = requests.get('https://api.target.com/data', proxies=proxies) print(response.status_code)
Verify the NTLM handshake is working by:
1. Check IIS logs for 401 responses followed by 200 2. Use Fiddler to inspect the auth headers 3. Test with curl through the local proxy: curl -x http://localhost:8080 http://example.com
If IIS isn't an option, consider these alternatives:
# Using ntlm-auth package from requests_ntlm import HttpNtlmAuth auth = HttpNtlmAuth('domain\\user','password') requests.get(url, proxies=proxies, auth=auth) # Or configure WinHTTP system-wide: netsh winhttp set proxy corporate.proxy.com:8080