使用Python Requests调用Azure Blob PUT API遇签名格式错误问题
问题:使用Python Requests上传Azure Blob时提示“Signature fields not well formed”
现象
通过Python Requests模块向Azure存储容器上传新Blob,收到认证错误:
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:a0bf7a23-d01e-0073-0b7c-e59eea000000 Time:2023-09-12T13:28:03.2249045Z</Message><AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail></Error>
涉事代码
import requests file_name = "test.txt" account = "<account_name>" container = "<container_name>" blob = "<blob_name>" key = "sp=rwdlacupiytfx&st=2023-07-10T15:59:34Z&se=2023-12-10T23:59:34Z&spr=https&sv=2022-11-02&sr=c&sig=<sig>" file = open(file_name, "rb") url = f"https://{account}.blob.core.windows.net/{container}/{blob}/{file_name}?{key}" print(url) headers = {'x-ms-version': '2020-10-02', 'x-ms-blob-type': 'BlockBlob'} test_response = requests.put(url, data = file, headers = headers) if test_response.ok: print("Upload completed successfully!") print(test_response.text) else: print("Something went wrong!") print(test_response.text)
解决步骤
1. 修正Blob URL路径
当前URL构造错误,Azure Blob的正确路径格式是https://{存储账户名}.blob.core.windows.net/{容器名}/{Blob名}?{SAS令牌}。代码里把blob和file_name拼接在一起,导致目标路径冗余,触发签名验证失败。
修改URL行,二选一即可:
- 若想用变量
blob作为Blob名称:
url = f"https://{account}.blob.core.windows.net/{container}/{blob}?{key}"
- 若想用
file_name作为Blob名称:
url = f"https://{account}.blob.core.windows.net/{container}/{file_name}?{key}"
2. 统一API版本
SAS令牌里指定的版本是sv=2022-11-02,但请求头的x-ms-version用了2020-10-02,版本不匹配会导致签名校验不通过。将请求头的API版本和SAS保持一致:
headers = {'x-ms-version': '2022-11-02', 'x-ms-blob-type': 'BlockBlob'}
3. 检查SAS令牌完整性
确认从Azure存储资源管理器复制的SAS令牌完整,尤其是sig=后面的签名部分,不能有截断、空格或多余字符。
修正后完整代码
import requests file_name = "test.txt" account = "<account_name>" container = "<container_name>" blob_name = "test.txt" # 按需指定Blob名称 sas_token = "sp=rwdlacupiytfx&st=2023-07-10T15:59:34Z&se=2023-12-10T23:59:34Z&spr=https&sv=2022-11-02&sr=c&sig=<sig>" # 使用with语句自动管理文件句柄,避免资源泄漏 with open(file_name, "rb") as file: url = f"https://{account}.blob.core.windows.net/{container}/{blob_name}?{sas_token}" headers = {'x-ms-version': '2022-11-02', 'x-ms-blob-type': 'BlockBlob'} test_response = requests.put(url, data=file, headers=headers) if test_response.ok: print("上传成功!") print(test_response.text) else: print("上传失败!") print(test_response.text)
内容的提问来源于stack exchange,提问作者Edoardo
相关产品推荐
相关产品推荐

