使用Python+Rest API通过SharedKey创建Azure Blob时签名认证失败
问题背景
无法使用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
相关产品推荐
相关产品推荐

