如何生成有效SAS令牌实现Azure服务总线队列认证并解决401错误?
解决Azure服务总线SAS令牌格式错误(401 MalformedToken)问题
你的代码生成的令牌出现解析错误,核心是两个关键问题:
问题1:资源URI格式错误
Azure要求SAS令牌的sr参数是不带https://前缀的服务总线资源路径,原代码中包含了https://,导致服务无法正确识别资源。
问题2:令牌参数分隔符错误
原代码用了HTML转义的&作为参数分隔符,实际应该使用普通的&,否则令牌会被判定为格式无效。
修正后的代码
import urllib.parse import hmac import hashlib import base64 import time def get_auth_token(sb_name, queue_name, sas_name, sas_value): """生成用于Service Bus REST API的授权令牌""" # 资源URI不带https://前缀 resource_uri = f"{sb_name}.servicebus.windows.net/{queue_name}" uri = urllib.parse.quote_plus(resource_uri) sas = sas_value.encode('utf-8') # 设置令牌过期时间(当前时间+10000秒) expiry = str(int(time.time() + 10000)) # 构造待签名字符串 string_to_sign = (uri + '\n' + expiry).encode('utf-8') # HMAC-SHA256签名 signed_hmac_sha256 = hmac.HMAC(sas, string_to_sign, hashlib.sha256) # 生成签名:base64编码后再URL编码 signature = urllib.parse.quote(base64.b64encode(signed_hmac_sha256.digest())) # 拼接令牌,使用&作为参数分隔符 token = f'SharedAccessSignature sr={uri}&sig={signature}&se={expiry}&skn={sas_name}' return { "sb_name": sb_name, "queue_name": queue_name, "token": token } # 替换为你的实际参数 sb_name = "my_service_bus" queue_name = "my_queue" sas_name = "shared_access_policy_name" sas_value = "my_primary_key" auth_token = get_auth_token(sb_name, queue_name, sas_name, sas_value) print(auth_token["token"])
验证REST请求示例
使用修正后的令牌发送消息到队列,示例代码(依赖requests库):
import requests import json # 构造请求URL request_url = f"https://{sb_name}.servicebus.windows.net/{queue_name}/messages" # 请求头配置 headers = { "Authorization": auth_token["token"], "Content-Type": "application/json" } # 消息内容 message_body = json.dumps({"content": "Hello from Service Bus REST API"}) # 发送POST请求 response = requests.post(request_url, headers=headers, data=message_body) print(f"响应状态码: {response.status_code}") if response.status_code == 201: print("消息发送成功") else: print(f"错误详情: {response.text}")
额外注意事项
- 确保你的共享访问策略(
sas_name)拥有发送(Send)权限,否则即使令牌有效也会返回403错误。 - 令牌过期时间建议按需设置,避免过长带来安全风险。
内容的提问来源于stack exchange,提问作者oorrii
相关产品推荐
相关产品推荐

