【Azure 存储服务】记一次调用Storage Blob API使用 SharedKey Authorization出现的403错误

简介: 【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

 

相关文章
|
23天前
|
安全 API 网络安全
【Azure API 管理】APIM不能连接到 App Service (APIM cannot connect to APP service)
【Azure API 管理】APIM不能连接到 App Service (APIM cannot connect to APP service)
|
23天前
|
API 开发工具 网络架构
【Azure Developer】如何通过Azure Portal快速获取到对应操作的API并转换为Python代码
【Azure Developer】如何通过Azure Portal快速获取到对应操作的API并转换为Python代码
|
23天前
|
存储 Kubernetes API
【APIM】Azure API Management Self-Host Gateway是否可以把请求的日志发送到Application Insights呢?让它和使用Azure上托管的 Gateway一样呢?
【APIM】Azure API Management Self-Host Gateway是否可以把请求的日志发送到Application Insights呢?让它和使用Azure上托管的 Gateway一样呢?
|
23天前
|
API 网络架构 C++
【Azure Key Vault】使用REST API调用Azure Key Vault Secret的示例步骤
【Azure Key Vault】使用REST API调用Azure Key Vault Secret的示例步骤
|
24天前
|
API 网络架构
【Azure Developer】使用 Microsoft Graph API查看用户状态和登录记录
【Azure Developer】使用 Microsoft Graph API查看用户状态和登录记录
|
1月前
|
机器人 API Python
智能对话机器人(通义版)会话接口API使用Quick Start
本文主要演示了如何使用python脚本快速调用智能对话机器人API接口,在参数获取的部分给出了具体的获取位置截图,这部分容易出错,第一次使用务必仔细参考接入参数获取的位置。
|
19天前
|
存储 JSON API
淘系API接口(解析返回的json数据)商品详情数据解析助力开发者
——在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦! 淘宝API接口(如淘宝开放平台提供的API)允许开发者获取淘宝商品的各种信息,包括商品详情。然而,需要注意的是,直接访问淘宝的商品数据API通常需要商家身份或开发者权限,并且需要遵循淘宝的API使用协议。
淘系API接口(解析返回的json数据)商品详情数据解析助力开发者
|
28天前
|
SQL 存储 数据处理
|
1月前
|
XML JSON API
RESTful API设计最佳实践:构建高效、可扩展的接口
【8月更文挑战第17天】RESTful API设计是一个涉及多方面因素的复杂过程。通过遵循上述最佳实践,开发者可以构建出更加高效、可扩展、易于维护的API。然而,值得注意的是,最佳实践并非一成不变,随着技术的发展和业务需求的变化,可能需要不断调整和优化API设计。因此,保持对新技术和最佳实践的关注,是成为一名优秀API设计师的关键。
|
1月前
|
监控 API 数据安全/隐私保护
​邮件API触发式接口分析?邮件API接口好评榜
邮件API在企业通信和营销中至关重要,通过自动化邮件发送流程提升效率与客户满意度。本文解析邮件API触发式接口,即基于特定事件(如用户注册、购买产品)自动发送邮件的技术,能显著加快企业响应速度并增强用户体验。推荐市场上的优秀邮件API产品,包括SendGrid、Mailgun、Amazon SES、Postmark及新兴的AOKSend,它们各具特色,如高发送率、详细分析工具、灵活配置、强大的日志功能及用户友好的API接口,帮助企业根据不同需求选择最合适的邮件API解决方案。