You need to enable JavaScript to run this app. 浏览器登录内网应用正常,curl/wget/Python请求返回401错误排查
优惠活动
大模型
产品
解决方案
定价
更多

浏览器登录内网应用正常,curl/wget/Python请求返回401错误排查

访问异常根本原因定位
  • 服务端未开启Basic/Digest认证,仅支持Negotiate(Kerberos/NTLM集成Windows认证)
    从所有响应的WWW-Authenticate响应头可以确认,服务端只下发了Negotiate、NTLM两种认证方式的标识,完全没有提及Basic、Digest协议。你之前尝试的所有Basic、Digest认证请求,都属于服务端不支持的认证方式,会被直接拦截返回401。
  • 现有工具的认证流程配置错误,未匹配到服务端要求的NTLM交互逻辑
    • curl调用时优先尝试了Negotiate分支的Kerberos认证,因本机无有效Kerberos凭据缓存(日志中gss_init_sec_context() failed就是该问题的直接表现)报错中断,没有回退到NTLM认证的交互流程
    • 系统自带版本的wget默认不支持NTLM协议,收到401响应后只会反复尝试Basic认证,最终判定授权失败
    • Python requests原生不支持NTLM认证,你调用的Basic、DigestAuth适配器无法和服务端完成NTLM的多步认证握手
  • Cookie流程是认证通过后的附属环节,不是独立的登录入口
    浏览器的访问逻辑是先完成HTTP层的NTLM/Negotiate认证,拿到有效身份后,服务端才会下发ASP.NET_SessionId、appname_Cookie、.application_SSO_Cookie等会话Cookie,后续请求携带这些Cookie即可保持会话。所有脚本请求因为第一步认证就被拦截,服务端根本不会下发会话Cookie,自然无法复现浏览器的200访问流程。
对应解决方案

curl 正确调用方式

强制跳过Kerberos优先分支,直接走NTLM认证,配合Cookie持久化模拟浏览器行为,执行命令:

curl --ntlm --user "DOMAIN\你的账号:密码" \
  --cookies-jar cookies.txt \
  --cookie cookies.txt \
  https://application.intranet.net/appname/Reporting/ReportListStart.aspx

参数说明:

  • --ntlm:指定走NTLM认证流程,避免优先触发Kerberos认证报错
  • --cookies-jar/--cookie:自动存储、携带服务端下发的会话Cookie,和浏览器行为一致
  • 用户名需要补全AD域前缀,格式和浏览器弹窗输入的完全一致(例如公司域\zhangsan)

wget 正确调用方式

系统默认wget不带NTLM支持,可使用以下参数强制匹配认证流程:

wget --http-user="DOMAIN\你的账号" \
  --http-password="你的密码" \
  --auth-no-challenge \
  --keep-session-cookies \
  --save-cookies cookies.txt \
  --load-cookies cookies.txt \
  https://application.intranet.net/appname/Reporting/ReportListStart.aspx

如果执行后仍反复返回401,说明当前wget版本未编译NTLM支持,建议直接使用Python方案替代。

Python requests 正确调用方式

原生requests不支持NTLM认证,需要安装对应扩展完成认证握手:

  1. 安装依赖:pip install requests-ntlm
  2. 参考实现代码:
import requests
from requests_ntlm import HttpNtlmAuth
from urllib.parse import urlparse

target_url = "https://application.intranet.net/appname/Reporting/ReportListStart.aspx"
# 用户名格式和浏览器输入保持一致,使用原始字符串避免转义问题
auth_user = r"DOMAIN\你的账号"
auth_pwd = "你的密码"

# 用Session自动管理Cookie,和浏览器会话逻辑一致
session = requests.Session()
session.auth = HttpNtlmAuth(auth_user, auth_pwd)

# 首次请求,关闭自动重定向以手动处理302流程
resp = session.get(target_url, allow_redirects=False, verify=True)
# 如果收到302重定向,自动携带Cookie请求跳转地址
if resp.status_code == 302:
    redirect_path = resp.headers.get("Location")
    if redirect_path.startswith("/"):
        parsed_url = urlparse(target_url)
        redirect_url = f"{parsed_url.scheme}://{parsed_url.netloc}{redirect_path}"
    else:
        redirect_url = redirect_path
    resp = session.get(redirect_url)

print(f"最终响应状态码:{resp.status_code}")
print(resp.text)

通用排查注意事项

  • 用户名格式必须和浏览器弹窗输入的完全一致,不能只写短用户名、也不能替换为邮箱格式,格式不匹配就算密码正确也会返回401
  • 如果按上述方法仍返回401,检查请求的Host头是否和浏览器访问的域名完全一致,部分内网应用会根据Host头校验认证合法性,错配Host头就算认证通过也会被拦截
  • 如果服务端强制启用Kerberos(Negotiate)认证、拒绝NTLM降级,需要先在客户端执行kinit 你的账号@公司域.COM缓存Kerberos票据,再通过curl的--negotiate参数、配合Python的requests-negotiate扩展完成认证,不需要传明文密码。

内容的提问来源于stack exchange,提问作者jsf80238

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.12 07:36:04