简体   繁体   English

Azure BLOB PUT Rest api - 无法使用 ZA7F5F353426B9238217316 进行身份验证

[英]Azure BLOB PUT Rest api - Not able to authenticate with Python

I'm trying to create a Blob in an Azure Container by using Python and the Azure Blob Rest API. I'm trying to create a Blob in an Azure Container by using Python and the Azure Blob Rest API. it has been an interesting exercise as it's my first time interacting with Azure Rest APIs.这是一个有趣的练习,因为这是我第一次与 Azure Rest API 交互。 I've read the MS documentation about it and also read many questions in this site and according to them my code seems correct however I am not able to make a successful PUT yet.我已经阅读了有关它的 MS 文档,还阅读了该站点中的许多问题,根据它们,我的代码似乎是正确的,但是我还不能成功 PUT。 I'm able to execute GET requests (list containers/blobs).我能够执行 GET 请求(列出容器/blob)。

Following the code:按照代码:

import requests
import datetime
import hmac
import hashlib
import base64

storage_account_name = '<mystorageaccount>'
storage_account_key = '<mystoragekey>'
container_name='test'
api_version = '2015-02-21'
request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': '11',
    'Content-MD5': '',
    'Content-Type': 'text/plain; charset=UTF-8',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlob' + '\nx-ms-date:' + request_time + '\nx-ms-version:' + api_version,
    'CanonicalizedResource': '/' + storage_account_name +'/'+container_name+ '/' +'fname'
}

string_to_sign = (string_params['verb'] + '\n' 
                  + string_params['Content-Encoding'] + '\n'
                  + string_params['Content-Language'] + '\n'
                  + string_params['Content-Length'] + '\n'
                  + string_params['Content-MD5'] + '\n' 
                  + string_params['Content-Type'] + '\n' 
                  + string_params['Date'] + '\n' 
                  + string_params['If-Modified-Since'] + '\n'
                  + string_params['If-Match'] + '\n'
                  + string_params['If-None-Match'] + '\n'
                  + string_params['If-Unmodified-Since'] + '\n'
                  + string_params['Range'] + '\n'
                  + string_params['CanonicalizedHeaders']
                  + string_params['CanonicalizedResource'])

signed_string = base64.b64encode(hmac.new(base64.b64decode(storage_account_key), msg=string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()).decode()

headers = {
    'x-ms-version' : api_version,
    'x-ms-date' : request_time,
    'x-ms-blob-type': 'BlockBlob',
    'Content-Length': '11',
    'Content-Type': "text/plain; charset=UTF-8",
    'Authorization' : ('SharedKey ' + storage_account_name + ':' + signed_string)
}

url = ('https://' + storage_account_name + '.blob.core.windows.net/'+container_name+'/fname')

r = requests.put(url, headers = headers,data='hello world')
print(r.status_code)
print('\n\n'+r.text)

That's the return error message I got not matter what:这就是我得到的返回错误消息,不管怎样:

<?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.
RequestId:cbf12c65-c01e-00fc-1069-3a41a7000000
Time:2020-06-04T12:11:03.4295368Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request 'c9n6EKq9p6skUs17qGv/bW0yGRGjMzMrP7bgDwjRABg=' is not the same as any computed signature. Server used following string to sign: 'PUT


11

text/plain; charset=UTF-8






x-ms-blob-type:BlockBlob
x-ms-date:Thu, 04 Jun 2020 12:11:02 GMT
x-ms-version:2015-02-21
/<mystorageaccount>/test/fname'.</AuthenticationErrorDetail></Error>

Can someone pls help me understand what I missing here?有人可以帮助我了解我在这里缺少什么吗?

You need to include text/plain; charset=UTF-8您需要包含text/plain; charset=UTF-8 text/plain; charset=UTF-8 for Content-Type and 11 for Content-Length in string_params . text/plain; charset=UTF-8用于Content-Type11用于string_params中的Content-Length So your revised code ( string_params variable only) would be something like:因此,您修改后的代码( string_params变量)将类似于:

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': '11',
    'Content-MD5': '',
    'Content-Type': 'text/plain; charset=UTF-8',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlob' + '\nx-ms-date:' + request_time + '\nx-ms-version:' + api_version,
    'CanonicalizedResource': '/' + storage_account_name +'/'+container_name+ '/' +'fname'
}

Rest of your code looks fine.您的代码的 Rest 看起来不错。

UPDATE更新

You're missing a new line character at the end of CanonicalizedHeaders .您在CanonicalizedHeaders末尾缺少一个换行符。 So your string_params will be like:所以你的string_params会像:

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': '11',
    'Content-MD5': '',
    'Content-Type': 'text/plain; charset=UTF-8',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlob' + '\nx-ms-date:' + request_time + '\nx-ms-version:' + api_version + '\n',
    'CanonicalizedResource': '/' + storage_account_name +'/'+container_name+ '/' +'fname'
}

Here is a simpler version of the code with more code reuse:这是一个更简单的代码版本,具有更多的代码重用:

def generate_key(verb, headers, content_type, storage_account_key, canonicalized_resource):
    string_to_sign = (verb + '\n'
                      + '\n' # Content-MD5
                      + content_type+ '\n'
                      + '\n' #Date
                      + "\n".join([k + ":" + v for k,v in headers.items()]) + '\n'
                      + canonicalized_resource)

    return base64.b64encode(
        hmac.new(base64.b64decode(storage_account_key), msg=string_to_sign.encode('utf-8'),
                 digestmod=hashlib.sha256).digest()).decode()

def request_with_headers(verb, storage_account_name, storage_account_key, container_name, blob_name, data = None):
    api_version = '2018-11-09'
    request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
    headers = {"x-ms-blob-type": "BlockBlob", "x-ms-date": request_time, "x-ms-version": api_version}
    canonicalized_resource = '/' + storage_account_name + '/' + container_name + '/' + blob_name
    content_type = "text/plain; charset=UTF-8"
    sas_token = generate_key(verb, headers, content_type, storage_account_key, canonicalized_resource)

    headers = dict(headers, **{"Content-Type": content_type, "Authorization": "SharedKeyLite %s:%s" % (storage_account_name, sas_token)})
    url = "https://%s.blob.core.windows.net/%s/%s" % (storage_account_name, container_name, blob_name)
    return requests.request(verb, url, headers=headers, data = data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Azure Runbooks 中使用 ZA7F5F35426B9637411FCZ3231B 验证 REST API - How to authenticate REST API in Azure Runbooks with Python? 使用REST API python将页面Blob上传到Azure - upload a page blob to azure using REST API python 如何编写 Python 脚本以对 Azure DevOps REST API 进行身份验证并获取访问令牌? - How to write a python script to authenticate to Azure DevOps REST API and get the access token? 如何使用Python中的Rest API对Azure数据目录进行身份验证并从中获取目录 - How do i authenticate to and get catalog from Azure Data Catalog using Rest API in Python 如何在python中针对Azure存储blob对用户进行身份验证? - How do I authenticate a user against an Azure storage blob in python? 使用Python 2.7对Tableau REST API进行身份验证 - Authenticate Tableau REST API using Python 2.7 Python rest api 放置方法抛出 500 - Python rest api Put method throws 500 使用Python向REST API提交请求 - PUT Request to REST API using Python python azure blob存储md5检查使用put_block_blob_from_path上传blob失败 - python azure blob storage md5 check fails on blob upload using put_block_blob_from_path REST API 从 Python 调用到 Z3A580F142203677F1F0BC3089ZF 的问题 - Issue with REST API call from Python to Azure
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM