使用API​​共享密钥在Azure Blob存储中获取Blob

时间:2019-06-02 17:19:29

标签: python azure-storage-blobs

我在Azure Blob存储中有一个(专用)Blob,它是通过具有写入和读取访问权限的帐户(它是通过terraform通过该帐户写入的)写入的。我正在尝试通过Python(没有Azure SDK)来获取它,但一直无法做到。

我的要求如下:

import datetime
import requests


key = ...
secret = ...
now = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
# the required settings, as per https://docs.microsoft.com/en-us/rest/api/storageservices/get-blob
headers = {'Authorization': 'SharedKey {}:{}'.format(key, secret),
           'Date': now,
           'x-ms-version': '2018-03-28'
           }

storage_account = ...
container = ...
url = 'https://{}.blob.core.windows.net/{}/terraform.tfstate'.format(storage_account, container)

response = requests.get(url, headers=headers)

print(response.status_code)
print(response.text)

这产生

400
<?xml version="1.0" encoding="utf-8"?><Error>
<Code>OutOfRangeInput</Code><Message>One of the request inputs is out of range. 
RequestId:...
Time:...</Message></Error>

我已经验证了该文件(存储浏览器)的存在,并且当我通过控制台访问该文件时,我得到的URL与上面的URL相同,但是带有额外的GET参数。


对于那些奇怪的事情:我决定不为Python使用Azure SDK的原因:我只需要获取一个Blob,pip install azure[blob]就会为项目添加 88 依赖项(IMO令人无法接受的高这个简单任务的编号)。

1 个答案:

答案 0 :(得分:0)

因此,原因是文档中提到的var arr = [ { "id": "1", "firstName": "Tom", "lastName": "Cruise", "position": 1 }, { "id": "2", "firstName": "Maria", "lastName": "Sharapova", "position": 2 }, { "id": "3", "firstName": "Robert", "lastName": "Downey Jr.", "position": 3 } ] function changePosition(from, to) { var startValue; var endValue; for (var l = 0; l < arr.length; l++) { if (arr[l].position == from) { startValue = arr[l].position; } if (arr[l].position == to) { endValue = arr[l].position; } } var i = Math.min(startValue, endValue); var j = Math.max(startValue, endValue); var inc = from > to ? 1 : -1; for (var k = 0; k < arr.length; k++) { if (arr[k].position >= i && arr[k].position <= j) { if (arr[k].position == from) { arr[k].position = to; } else { arr[k].position += inc; } } } } changePosition(3, 1); console.log(arr);是根据请求构建的,并在here中进行了详细描述。

Python 3等效的是:

signature

其中import base64 import hmac import hashlib import datetime import requests def _sign_string(key, string_to_sign): key = base64.b64decode(key.encode('utf-8')) string_to_sign = string_to_sign.encode('utf-8') signed_hmac_sha256 = hmac.HMAC(key, string_to_sign, hashlib.sha256) digest = signed_hmac_sha256.digest() encoded_digest = base64.b64encode(digest).decode('utf-8') return encoded_digest def get_blob(storage_account, token, file_path): now = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') url = 'https://{account}.blob.core.windows.net/{path}'.format(account=storage_account, path=file_path) version = '2018-03-28' headers = {'x-ms-version': version, 'x-ms-date': now} content = 'GET{spaces}x-ms-date:{now}\nx-ms-version:{version}\n/{account}/{path}'.format( spaces='\n'*12, now=now, version=version, account=storage_account, path=file_path ) headers['Authorization'] = 'SharedKey ' + storage_account + ':' + _sign_string(token, content) response = requests.get(url, headers=headers) assert response.status_code == 200 return response.text 的格式为file_path

使用此代码段仍然可以为项目添加88个依赖项。