使用Python SDK+SAS令牌复制私有Blob时遇AuthorizationPermissionMismatch错误
问题概述
尝试使用Azure Python SDK通过账户SAS令牌复制私有存储账户间的Blob时,出现AuthorizationPermissionMismatch未授权错误,错误详情如下:
Failed to copy blob. Error:This request is not authorized to perform this operation using this permission.
RequestId:8a33f614-601e-011b-7df6-51dc91000000
Time:2023-03-08T19:43:17.3158296Z
ErrorCode:AuthorizationPermissionMismatch
Content:return (<Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission. RequestId:8a33f614-601e-011b-7df6-51dc91000000 Time:2023-03-08T19:43:17.3158296Z</Message></Error>)
代码问题分析
- 变量名混乱与未定义:源存储账户的连接字符串、密钥变量名错误,
src_account_key未正确赋值;目标容器变量混淆,dest_container_name被错误设置为Blob路径而非容器名。 - 目标SAS权限不足:执行
start_copy_from_url需要对目标Blob拥有写入权限,但当前目标SAS仅授予read和list权限,无法完成写入操作。 - 时区时间问题:SAS令牌的
start时间使用本地时间datetime.now(),可能因时区差导致令牌未及时生效,应统一使用UTC时间。
修正后的代码
from azure.storage.blob import BlobClient, BlobServiceClient from azure.storage.blob import ResourceTypes, AccountSasPermissions from azure.storage.blob import generate_account_sas from datetime import datetime, timedelta # 源存储账户凭证 src_connection_string = '<源存储账户连接字符串>' src_account_key = "<源存储账户密钥>" src_container_name = 'con1' src_blob_name = "demo1/folder1/file.txt" # 目标存储账户凭证 dest_connection_string = '<目标存储账户连接字符串>' dest_account_key = "<目标存储账户密钥>" dest_container_name = "con1" # 正确的目标容器名 dest_blob_name = "demo2/file.txt" # 创建源服务客户端 src_client = BlobServiceClient.from_connection_string(src_connection_string) # 创建目标服务客户端 dest_client = BlobServiceClient.from_connection_string(dest_connection_string) # 生成源账户SAS令牌(仅需read权限) src_sas_token = generate_account_sas( account_name = src_client.account_name, account_key = src_account_key, resource_types = ResourceTypes(object=True), # 仅需object级权限 permission= AccountSasPermissions(read=True), start = datetime.utcnow(), expiry = datetime.utcnow() + timedelta(hours=4) ) # 生成目标账户SAS令牌(需要write权限) dest_sas_token = generate_account_sas( account_name = dest_client.account_name, account_key = dest_account_key, resource_types = ResourceTypes(object=True), permission= AccountSasPermissions(write=True), # 添加write权限以完成写入 start = datetime.utcnow(), expiry = datetime.utcnow() + timedelta(hours=4) ) # 源Blob客户端 src_blob_client = BlobClient( src_client.url, container_name = src_container_name, blob_name = src_blob_name, credential = src_sas_token ) # 目标Blob客户端 dest_blob_client = BlobClient( dest_client.url, container_name = dest_container_name, blob_name = dest_blob_name, credential = dest_sas_token ) # 执行复制操作 try: copy_result = dest_blob_client.start_copy_from_url(src_blob_client.url) # 轮询复制状态(可选,确保复制完成) while True: props = dest_blob_client.get_blob_properties() print(f"复制状态: {props.copy.status}") if props.copy.status not in ['pending']: break except Exception as e: print(f"复制失败. 错误: {str(e)}")
关键修正说明
- 权限调整:目标SAS必须包含
write权限,因为start_copy_from_url本质是向目标存储账户写入Blob数据。 - 资源类型优化:仅指定
object=True即可,无需container=True,遵循最小权限原则提升安全性。 - 时间统一:使用
datetime.utcnow()避免时区差异导致的令牌生效延迟。 - 变量校验:确保所有凭证变量名正确,容器名与Blob路径不混淆。
内容的提问来源于stack exchange,提问作者SidharthPradhan
相关产品推荐
相关产品推荐

