【问题标题】:PUT request to Azure storage with shared key authorization使用共享密钥授权向 Azure 存储 PUT 请求
【发布时间】:2018-10-16 16:10:37
【问题描述】:

我正在尝试向 Azure 存储发出 put 请求,主要是更改存储属性。虽然我可以按照这里的教程https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key#Subheading2 使 GET 请求工作,但我没有看到一个合适的在那里构造 PUT 请求。

所以,在搜索时我得到了这个,但使用了 get,can't connect to azure file service REST api by python,但这又是一个 GET 请求。对于 PUT 请求总是得到 HTTP 403,我不确定它在哪里失败。这是链接中修改后的代码,用于描述我在代码中所做的事情。

import requests
import datetime
import hmac
import hashlib
import base64

storage_account_name = 'strtest'
storage_account_key = 'key'
api_version = '2016-05-31'
request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': '',
    'Content-MD5': '',
    'Content-Type': 'application/xml',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-date:' + request_time + '\nx-ms-version:' + api_version + '\n',
    'CanonicalizedResource': '/' + storage_account_name + '/\ncomp:properties\nrestype:service'
}

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-date' : request_time,
    'x-ms-version' : api_version,
    'Authorization' : ('SharedKey ' + storage_account_name + ':' + signed_string)
}

url = ('https://' + storage_account_name + '.blob.core.windows.net/?restype=service&comp=properties')

data = """<StorageServiceProperties></StorageServiceProperties>"""

r = requests.put(url, headers = headers, data = data)

print(r.content)

尝试发送的内容是 XML 格式。虽然代码正在处理 GET 请求,但 PUT 不是。

【问题讨论】:

  • 请在您的headers 定义中添加Content-Type 标头。
  • 谢谢,我已经在标题中添加了,仍然得到相同的结果。

标签: python azure authorization azure-storage azure-blob-storage


【解决方案1】:

除了Content-Type,对于put请求,你还需要在string_params中填写Content-Length,因为对应的header可能是sdk自动设置的。

【讨论】:

  • 谢谢,我能够在添加内容长度后使其工作,我做错的是添加内容长度并输入规范标题。这是错误的。我已经更新了下面的工作代码以供参考,可能对某人有帮助。
【解决方案2】:

这是工作代码。

import requests
import datetime
import hmac
import hashlib
import base64

storage_account_name = 'acc_name'
storage_account_key = 'ac_key'
api_version = '2018-03-28'
request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
data = "<StorageServiceProperties></StorageServiceProperties>"
content_len = str(len(data))

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': content_len,
    'Content-MD5': '',
    'Content-Type': 'application/xml',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-date:' + request_time + '\nx-ms-version:' + api_version + '\n',
    'CanonicalizedResource': '/' + storage_account_name + '/\ncomp:properties\nrestype:service'
}

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-date' : request_time,
    'x-ms-version' : api_version,
    'Content-Type': 'application/xml',
    'Content-Length': content_len,
    'Authorization' : ('SharedKey ' + storage_account_name + ':' + signed_string)
}

url = ('https://' + storage_account_name + '.blob.core.windows.net/?restype=service&comp=properties')

data = "<StorageServiceProperties></StorageServiceProperties>"

r = requests.put(url, headers = headers, data=data)

print(r.content)

【讨论】:

    猜你喜欢
    • 2020-10-10
    • 2018-12-05
    • 1970-01-01
    • 2015-04-26
    • 2013-06-19
    • 2021-10-30
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多