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

使用Python+Rest API通过SharedKey创建Azure Blob时签名认证失败

Azure Blob SharedKey 认证失败排查(自定义Python实现)

问题背景

无法使用Azure Blob Python SDK,需手动通过SharedKey认证上传Blob,但请求始终返回AuthenticationFailed错误,问题大概率出在签名构造环节。

代码片段

import requests
import hmac
import hashlib
import base64
from datetime import datetime

# 配置信息
account_name = "your_account_name"
account_key = "your_account_key"
container_name = "test-container"
blob_name = "test.txt"
content = "Hello Azure Blob"

# 构造请求头
utc_now = datetime.utcnow()
date_str = utc_now.strftime('%a, %d %b %Y %H:%M:%S GMT')
headers = {
    'x-ms-date': date_str,
    'x-ms-version': '2021-06-08',
    'Content-Length': str(len(content)),
    'Content-Type': 'text/plain'
}

# 构造待签名字符串
string_to_sign = f"""PUT
{len(content)}
text/plain

x-ms-date:{date_str}
x-ms-version:2021-06-08
/{account_name}/{container_name}/{blob_name}"""

# 生成签名
decoded_account_key = base64.b64decode(account_key)
signature_bytes = hmac.new(decoded_account_key, string_to_sign.encode('utf-8'), hashlib.sha256).digest()
encoded_signature = base64.b64encode(signature_bytes).decode('utf-8')
auth_header = f"SharedKey {account_name}:{encoded_signature}"
headers['Authorization'] = auth_header

# 发送上传请求
blob_url = f"https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}"
response = requests.put(blob_url, headers=headers, data=content)

print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")

生成的签名字符串与错误信息

生成的string_to_sign:

PUT
15
text/plain

x-ms-date:Wed, 10 Jul 2024 12:34:56 GMT
x-ms-version:2021-06-08
/your_account_name/test-container/test.txt

服务器返回错误:

<?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:xxxx-xxxx-xxxx-xxxx-xxxx
Time:2024-07-10T12:34:57Z</Message>
  <AuthenticationErrorDetail>The MAC signature found in the HTTP request 'xxxxxx' is not the same as any computed signature. Server used following string to sign: 'PUT
15
text/plain

x-ms-date:Wed, 10 Jul 2024 12:34:56 GMT
x-ms-version:2021-06-08
/your_account_name/test-container/test.txt'</AuthenticationErrorDetail>
</Error>

核心排查与修复点

  • 严格匹配签名字符串格式:
    SharedKey的string_to_sign必须严格遵循固定顺序,每个字段用换行分隔,空行不能省略。规范格式为:

    HTTP方法
    Content-MD5(未设置则留空)
    Content-Type
    空行
    所有x-ms-开头的请求头(按字母顺序排列,格式为`key:value`)
    /账户名/容器名/Blob名
    

    若请求未设置Content-MD5,对应位置必须留空行,不能直接跳过。

  • 验证时间戳一致性:
    x-ms-date必须是UTC时间,且与Azure服务器时间差不超过15分钟。确保使用datetime.utcnow()生成时间,避免本地时区偏差。

  • 检查HTTP方法与路径:
    HTTP方法必须大写(如PUT);路径部分必须是/{account_name}/{container_name}/{blob_name},不能多斜杠或遗漏账户名。

  • 编码与签名生成逻辑:

    • 账户密钥需先Base64解码为字节,再用于HMAC-SHA256计算
    • string_to_sign必须用UTF-8编码后再计算签名
    • 最终签名需Base64编码为字符串,再放入Authorization头
  • x-ms-header排序:
    所有x-ms-开头的请求头必须按字母顺序排列在string_to_sign中,比如x-ms-date要在x-ms-version之前(按首字母排序规则)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:57:21