You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Curl摘要认证失败求助:无法发起二次请求完成认证

Curl摘要认证无法发起二次请求的问题解决

我通过Shell脚本使用Curl尝试通过Digest Authorization连接HTTP服务器,但Curl始终没有发起完成摘要认证所需的第二次请求。

Curl输出如下:

* Expire in 1 ms for 1 (transfer 0x4fb960)
*   Trying 192.168.17.24...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x4fb960)
* Connected to xxx (192.168.17.24) port 80 (#0)
* Server auth using Digest with user 'user'
> POST /config/timeofuse HTTP/1.1
> Host: xxx
> User-Agent: curl/7.64.0
> Accept: application/json, text/plain, */*
> Content-Type: application/json
> Content-Length: 0
>
< HTTP/1.1 401 Unauthorized
< X-WWW-Authenticate: Digest realm="Webinterface area", charset="UTF-8", algorithm=MD5, nonce="6463d513:3927ccc8e06b0a9d4ec28f0bc9d863bc", qop="auth"
< Content-Type: text/html
< Content-Length: 347
< Date: Tue, 16 May 2023 19:10:11 GMT
< Server: webserver
<
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 Unauthorized</title>
 </head>
 <body>
  <h1>401 Unauthorized</h1>
 </body>
</html>
* Connection #0 to host xxx left intact

我推测问题出在Curl需要标准的WWW-Authenticate响应头,但服务器返回的是X-WWW-Authenticate头,而且因为是嵌入式设备,没法修改服务器配置。想请教两个问题:
a) 我的推测是否正确?还是有其他问题?
b) 有没有办法让Curl把X-WWW-Authenticate头当作WWW-Authenticate头处理?

我试过httpie,遇到同样问题;查阅了Curl手册,未找到相关设置。


问题a的解答

你的推测完全正确。根据HTTP标准,摘要认证要求服务器在401响应中返回WWW-Authenticate头传递认证参数,而Curl、httpie这类工具只会识别标准的WWW-Authenticate头,对非标准的X-WWW-Authenticate头不会触发自动处理流程,因此不会发起第二次携带认证信息的请求。

问题b的解答

Curl本身没有直接配置项支持识别X-WWW-Authenticate头,但可以通过两种方式解决:

方法1:手动构造Digest认证头

  1. 从服务器返回的X-WWW-Authenticate头中提取关键参数:realm、nonce、qop、algorithm。
  2. 手动计算摘要认证所需的哈希值,构造Authorization头。
  3. 在Curl请求中直接添加该头。

示例操作:
假设提取到的参数为:

  • realm: "Webinterface area"
  • nonce: "6463d513:3927ccc8e06b0a9d4ec28f0bc9d863bc"
  • qop: "auth"
  • algorithm: MD5
    用户名user,密码your_password,请求方法POST,路径/config/timeofuse。

计算哈希值:

# 计算HA1:MD5(用户名:域:密码)
HA1=$(echo -n "user:Webinterface area:your_password" | openssl md5 | cut -d' ' -f2)
# 计算HA2:MD5(请求方法:请求路径)
HA2=$(echo -n "POST:/config/timeofuse" | openssl md5 | cut -d' ' -f2)
# 生成随机cnonce(示例用固定值,实际可生成随机字符串)
CNONCE="abc123"
# 请求计数,首次请求用00000001
NC="00000001"
# 计算最终响应值
RESPONSE=$(echo -n "$HA1:6463d513:3927ccc8e06b0a9d4ec28f0bc9d863bc:$NC:$CNONCE:auth:$HA2" | openssl md5 | cut -d' ' -f2)

构造Curl请求:

curl -X POST http://xxx/config/timeofuse \
  -H "Content-Type: application/json" \
  -H 'Authorization: Digest username="user", realm="Webinterface area", nonce="6463d513:3927ccc8e06b0a9d4ec28f0bc9d863bc", uri="/config/timeofuse", qop=auth, nc=00000001, cnonce="abc123", response="'$RESPONSE'", algorithm=MD5' \
  -d '{}'

方法2:通过代理修改响应头

使用中间代理拦截服务器响应,将X-WWW-Authenticate头替换为标准的WWW-Authenticate,让Curl自动处理认证流程。

比如用mitmproxy实现:

  1. 创建代理脚本modify_auth_header.py:
from mitmproxy import http

def response(flow: http.HTTPFlow) -> None:
    if flow.response.status_code == 401:
        if "X-WWW-Authenticate" in flow.response.headers:
            auth_value = flow.response.headers.pop("X-WWW-Authenticate")
            flow.response.headers["WWW-Authenticate"] = auth_value
  1. 启动mitmproxy并加载脚本:
mitmproxy -s modify_auth_header.py
  1. 通过代理发起Curl请求:
curl -x http://localhost:8080 -u user:your_password -X POST http://xxx/config/timeofuse -H "Content-Type: application/json" -d '{}'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:35:41