如何在WebDAV中拒绝HTTP Authorization: Negotiate请求且不干扰客户端?
处理WSGIDav中MS Office发起的无意义NTLM协商请求
针对你遇到的MS Office突然发起空体LOCK/PUT+Negotiate头部的问题,结合WSGIDav的认证逻辑,给你以下具体的处理方案:
核心判断逻辑
先精准识别需要拦截的请求:
- 请求方法为LOCK或PUT
- 请求体为空(
Content-Length: 0) - 携带
Authorization: Negotiate ...头部 - 客户端已持有有效的认证Cookie(或通过秘钥URL完成过认证)
正确的响应方式
直接返回400 Bad Request,绝对不要用401 Unauthorized:
- 400能明确告知客户端这是无效请求,不会触发NTLM的重试协商流程(如果返回401,Office会反复发起协商,反而加重问题)
- 响应体可以简单说明原因,比如:
Invalid request: Empty body with unnecessary Negotiate auth header
在WSGIDav中落地实现
写一个自定义WSGI中间件,在请求进入WebDAV核心逻辑前拦截:
class BlockUnwantedNegotiate: def __init__(self, app): self.app = app def __call__(self, environ, start_response): # 提取关键请求参数 req_method = environ.get("REQUEST_METHOD", "") auth_header = environ.get("HTTP_AUTHORIZATION", "") content_len = environ.get("CONTENT_LENGTH", "0") # 检查是否有有效认证Cookie(替换成你的Cookie名称) has_valid_cookie = "your_auth_cookie_name" in environ.get("HTTP_COOKIE", "") # 命中拦截条件 if (req_method in ("LOCK", "PUT") and auth_header.startswith("Negotiate ") and content_len == "0" and has_valid_cookie): # 返回400响应 start_response("400 Bad Request", [("Content-Type", "text/plain")]) return [b"Invalid request: Empty body with unnecessary Negotiate authorization header"] # 正常请求放行 return self.app(environ, start_response)
把这个中间件加到WSGIDav的应用链里,注意要放在你的Cookie认证中间件之后,确保先验证用户已合法认证。
额外注意点
- 测试时覆盖不同版本的MS Office,确认返回400后客户端不会弹出错误提示或影响正常操作
- 可以在日志里记录这类请求的客户端UA、IP等信息,方便后续定位触发原因
内容的提问来源于stack exchange,提问作者Dave Vogt
相关产品推荐
相关产品推荐

