【Azure 存储服务】记一次调用Storage Blob API使用 SharedKey Authorization出现的403错误
问题描述
使用Azure Storag Blob REST API上传文件,用SharedKey作为Authorization出现403错误。
错误消息
b'\xef\xbb\xbf<?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.\nRequestId:7df1f139-901e-0063-64eb-4be2dc000000\nTime:2023-03-01T03:08:27.3277224Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request \’*\' is not the same as any computed signature. Server used following string to sign: \'PUT\n\n\n19122\n\ntext/plain; charset=UTF-8\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Wed, 01 Mar 2023 03:08:26 GMT\nx-ms-version:2015-02-21\n/adlstestaccount/blobtest/20230220065800824-2696.jpg\'.</AuthenticationErrorDetail></Error>' reason=Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
问题发现
在错误消息“Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.”中,提到了请求SharedKey 中的内容和请求Header中的内容不一致。
检查生成SharedKey 的代码
第一步:生成put_str
put_str = u"PUT\n\n\n{}\n\n{}; charset={}\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:{}\nx-ms-version:{}\n/{}/{}/{}".format(str(len(file)),
'text/plain' ,
'UTF-8',
get_date(),
'2015-02-21',
'<your storage account name>',
'<container name>',
file_name)
sig_str = base64.b64encode(hmac.new(account_key_decoded, put_str, digestmod=hashlib.sha256).digest()).decode('utf-8')
第二步:请求的Header中,通过Authorization 传递 sig_str
headers = {
"x-ms-blob-type": "BlockBlob",
"x-ms-date": get_date(),
"x-ms-version": "2015-02-21",
"Authorization": "SharedKey {}:{}".format("adlstestaccount", sig_str),
"Content-Type": "{}; charset={}".format('text/plain', 'UTF-8'),
"Content-Length": str(len(file))
}
在调试代码的过程中,对比 put_str 内容和 blob服务端 SharedKey信息,发现它们的 x-ms-date 部分值不一样:

因SharedKey不一样,所以认证时候出现403 Server failed to authenticate the request.
在第一步生成 put_str 的时候获取 x-ms-date 的时候调用的 get_date() 获取时间,第二步在生成Header x-ms-date的时候再一次调用 get_date() 获取时间,由于代码在执行时候出现了时间差,这就导致了header中的时间和Authorization SharedKey中时间不一致。这就是出现403的根本原因。
解决办法就是在获取x-ms-date的时候,不要两次调用get_date()方法,而是只调用一次,然后put_str和header中都使用同一个时间值。
修改后的代码片段为
//获取时间
ms_date = get_date(); put_str = u"PUT\n\n\n{}\n\n{}; charset={}\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:{}\nx-ms-version:{}\n/{}/{}/{}".format(str(len(file)),
'text/plain' ,
'UTF-8',
ms_date,
'2015-02-21',
'<your storage account name>',
'<container name>',
file_name) sig_str = base64.b64encode(hmac.new(account_key_decoded, put_str, digestmod=hashlib.sha256).digest()).decode('utf-8') headers = {
"x-ms-blob-type": "BlockBlob",
"x-ms-date": ms_date,
"x-ms-version": "2015-02-21",
"Authorization": "SharedKey {}:{}".format("adlstestaccount", sig_str),
"Content-Type": "{}; charset={}".format('text/plain', 'UTF-8'),
"Content-Length": str(len(file))
}
附录:使用AAD 和 Storage Account Access Key进行认证获取Blob的Python实例代码
from azure.storage.filedatalake import DataLakeServiceClient
from azure.identity import ClientSecretCredential
from azure.identity import AzureAuthorityHosts tenant_id = "*"
client_id = "*"
client_secret = "*"
authority = AzureAuthorityHosts.AZURE_CHINA
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret,authority=authority)
account_url = "*"
account_key = "*"
container="*"
folder="*"
connection_string = "*" def initialize_storage_account():
try:
global service_client
#使用AAD 认证
#service_client = DataLakeServiceClient(account_url=account_url, credential=credential) #使用Access Key认证
service_client = DataLakeServiceClient.from_connection_string(connection_string)
except Exception as e:
print(e) def list_directory_contents():
try:
file_system_client = service_client.get_file_system_client(file_system=container)
paths = file_system_client.get_paths(path=folder)
for path in paths:
print(path.name + '\n')
except Exception as e:
print(e) initialize_storage_account()
list_directory_contents()
参考资料
通过共享密钥进行授权 : https://learn.microsoft.com/zh-cn/rest/api/storageservices/authorize-with-shared-key
Azure Blob 存储和 Python 入门 : https://learn.microsoft.com/zh-cn/azure/storage/blobs/storage-blob-python-get-started?tabs=azure-ad
【Azure 存储服务】记一次调用Storage Blob API使用 SharedKey Authorization出现的403错误的更多相关文章
- 【Azure 存储服务】代码版 Azure Storage Blob 生成 SAS (Shared Access Signature: 共享访问签名)
问题描述 在使用Azure存储服务,为了有效的保护Storage的Access Keys.可以使用另一种授权方式访问资源(Shared Access Signature: 共享访问签名), 它的好处可 ...
- 【Azure 存储服务】.NET7.0 示例代码之上传大文件到Azure Storage Blob
问题描述 在使用Azure的存储服务时候,如果上传的文件大于了100MB, 1GB的情况下,如何上传呢? 问题解答 使用Azure存储服务时,如果要上传文件到Azure Blob,有很多种工具可以实现 ...
- 【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
问题描述 使用Azure Storage Account的共享访问签名(Share Access Signature) 生成的终结点,连接时遇见 The Azure Storage endpoint ...
- 解读 Windows Azure 存储服务的账单 – 带宽、事务数量,以及容量
经常有人询问我们,如何估算 Windows Azure 存储服务的成本,以便了解如何更好地构建一个经济有效的应用程序.本文我们将从带宽.事务数量,以及容量这三种存储成本的角度探讨这一问题. 在使用 W ...
- 玩转Windows Azure存储服务——网盘
存储服务是除了计算服务之外最重要的云服务之一.说到云存储,大家可以想到很多产品,例如:AWS S3,Google Drive,百度云盘...而在Windows Azure中,存储服务却是在默默无闻的工 ...
- 【Azure 存储服务】Python模块(azure.cosmosdb.table)直接对表存储(Storage Account Table)做操作示例
什么是表存储 Azure 表存储是一项用于在云中存储结构化 NoSQL 数据的服务,通过无结构化的设计提供键/属性存储. 因为表存储无固定的数据结构要求,因此可以很容易地随着应用程序需求的发展使数据适 ...
- 玩转Windows Azure存储服务——高级存储
在上一篇我们把Windows Azure的存储服务用作网盘,本篇我们继续挖掘Windows Azure的存储服务——高级存储.高级存储自然要比普通存储高大上的,因为高级存储是SSD存储!其吞吐量和IO ...
- 【Azure 存储服务】如何把开启NFS 3.0协议的Azure Blob挂载在Linux VM中呢?(NFS: Network File System 网络文件系统)
问题描述 如何把开启NFS协议的Azure Blob挂载到Linux虚拟机中呢? [答案]:可以使用 NFS 3.0 协议从基于 Linux 的 Azure 虚拟机 (VM) 或在本地运行的 Linu ...
- 【Azure 存储服务】Hadoop集群中使用ADLS(Azure Data Lake Storage)过程中遇见执行PUT操作报错
问题描述 在Hadoop集中中,使用ADLS 作为数据源,在执行PUT操作(上传文件到ADLS中),遇见 400错误[put: Operation failed: "An HTTP head ...
- S3 服务(Simple Storage Service简单存储服务) 简介(与hdfs同一级)
图1 spark 相关 亚马逊云存储之S3(Simple Storage Service简单存储服务) (转 ) S3是Simple Storage Service的缩写,即简单存储服务.亚马逊的名 ...
随机推荐
- JVM内存学习 2.0
先说一下结果 1. Linux的内存分配是惰性分配的. APP申明了 kernel并不会立即进行初始化和使用. 2. JVM的内存主要分为, 堆区, 非堆区, 以及jvm使用的其他内存. 比如直接内存 ...
- 【码农教程】手把手教你学会Mockito使用
作者:京东零售 秦浩然 一.前期准备- 1.准备工作 <!--mockito依赖--> <dependency> <groupId>org.mockito</ ...
- 分布式事务和Spanner分布式数据库
一.分布式事务 首先事务可以这么理解:程序员有一些不同的操作,或许针对数据库不同的记录,他们希望所有这些操作作为一个整体,不会因为失败而被分割,也不会被其他活动看到中间状态.事务处理系统要求程序员对这 ...
- 重新学习一下new Date()
new Date()你知道多少 很多小伙伴可能都知道, Date是js中的一个内置对象,用于处理日期和时间. 当你调用 new Date() 时,它会创建一个新的日期(Date) 对象. 表示当前本地 ...
- python处理Excel实现自动化办公教学(数据筛选、公式操作、单元格拆分合并、冻结窗口、图表绘制等)【三】
相关文章: python处理Excel实现自动化办公教学(含实战)[一] python处理Excel实现自动化办公教学(含实战)[二] python处理Excel实现自动化办公教学(数据筛选.公式操作 ...
- 知识图谱项目实战(一):瑞金医院MMC人工智能辅助构建知识图谱--初赛实体识别【1】
1.技术背景&赛题介绍: A Labeled Chinese Dataset for Diabetes中文糖尿病标注数据集详情请见. 数据集链接:瑞金医院MMC人工智能辅助构建知识数据源:知识 ...
- Linux文件IO之二 [补档-2023-07-21]
8-5 linux系统IO函数: open函数: 函数原型:int open(const char *pathname, int flags, mode_t mode); 功能:打开一个文件并 ...
- 由刷题学习 heapq
今日一题是 面试题 17.14. 最小K个数 https://leetcode-cn.com/problems/smallest-k-lcci/ 还好 提示 0 <= len(arr) < ...
- Python下的三维建模和可视化
本文介绍基于AnyCAD Rapid Py三维图形平台开发Python的三维应用 1 准备工作 1.1 安装 vc_resit 2022 在Windows下,AnyCAD Rapid SDK依赖Vis ...
- 会话跟踪技术之SESSION
会话跟踪技术之SESSION 一般来说,登录信息既可以存储在session中,也可以存储在cookie中,他们之间的差别在于session可以方便的存取多种数据类型,而cookie只支持字符串类型,同 ...