Python生成Azure文件共享SAS令牌时签名不匹配问题排查
问题描述
编写了如下Python代码用于生成Azure文件共享中文件的SAS令牌:
def getParcelFilePath(webcountyval): filePath = rf"/plan/IN/{webcountyval}%20parcels.dbf" file_sas_token = generate_file_sas( account_name=os.environ["AZURE_STORAGE_ACCOUNT_NAME"], account_key=os.environ["AZURE_STORAGE_ACCOUNT_KEY"], share_name="dev", file_path=filePath, permission=AccountSasPermissions(read=True), expiry=datetime.datetime.now() + datetime.timedelta(hours=8), start=datetime.datetime.now() ) filePathWithToken = os.environ["AZURE_STORAGE_SHARE_URL"] + filePath + "?" + file_sas_token return(filePathWithToken)
生成的URL粘贴到浏览器后,出现签名不匹配错误:
Signature did not match. String to sign used was r 2024-11-11T23:14:30Z 2024-11-12T07:14:30Z /file/crestlinecapitalstorage/dev/plan/IN/elkhart parcels.dbf 2024-11-04
原因分析
文件路径编码错误:
generate_file_sas函数要求传入文件在存储中的原始未编码路径(即空格就是空格,而非%20)。但代码中直接将URL编码后的%20传入file_path参数,导致Azure计算签名时使用的路径是/plan/IN/elkhart%20parcels.dbf,而实际验证时系统会自动解码为带空格的路径/plan/IN/elkhart parcels.dbf,两者不一致导致签名验证失败。时间时区潜在问题:使用
datetime.datetime.now()获取本地时间(中部时区),手动加8小时转换为UTC的方式依赖本地系统时区设置,容易出现偏差。Azure SAS要求使用UTC时间,直接调用utcnow()更可靠。
修复方案
修改代码关键点:
- 传给
generate_file_sas的file_path使用原始带空格的路径,不要提前URL编码 - 时间部分改用
datetime.datetime.utcnow()获取UTC时间 - 拼接最终URL时,再对文件路径进行URL编码
修改后的代码:
import urllib.parse import datetime from azure.storage.fileshare import generate_file_sas, AccountSasPermissions import os def getParcelFilePath(webcountyval): # 使用存储中的原始路径(带空格,不编码) filePath = rf"/plan/IN/{webcountyval} parcels.dbf" file_sas_token = generate_file_sas( account_name=os.environ["AZURE_STORAGE_ACCOUNT_NAME"], account_key=os.environ["AZURE_STORAGE_ACCOUNT_KEY"], share_name="dev", file_path=filePath, permission=AccountSasPermissions(read=True), # 使用UTC时间,避免本地时区干扰 expiry=datetime.datetime.utcnow() + datetime.timedelta(hours=8), start=datetime.datetime.utcnow() ) # 拼接URL时对路径进行URL编码,去掉开头斜杠避免重复 encoded_file_path = urllib.parse.quote(filePath.lstrip('/')) filePathWithToken = f"{os.environ['AZURE_STORAGE_SHARE_URL']}/{encoded_file_path}?{file_sas_token}" return filePathWithToken
验证说明:
修改后,生成SAS时使用的路径和Azure验证时的路径一致(均为带空格的原始路径),签名计算会匹配;同时UTC时间的使用避免了时区导致的时间偏差,进一步保证认证通过。
内容的提问来源于stack exchange,提问作者anilcreates
相关产品推荐
相关产品推荐

