Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何为Azure Cosmos DB REST API构建哈希令牌签名以列出用户?_Python_Azure_Api_Azure Cosmosdb_Unauthorized - Fatal编程技术网

Python 如何为Azure Cosmos DB REST API构建哈希令牌签名以列出用户?

Python 如何为Azure Cosmos DB REST API构建哈希令牌签名以列出用户?,python,azure,api,azure-cosmosdb,unauthorized,Python,Azure,Api,Azure Cosmosdb,Unauthorized,根据Cosmos DB REST API的文档,每个API调用都必须设置授权头。该值的构造如下所述: 我正在用Python实现这一点,如下所示: def get_authorisation_token(verb, resource_type, resource_id, date, master_key): key = base64.b64decode(master_key) text = f"""{verb.lower()}\n{resourc

根据Cosmos DB REST API的文档,每个API调用都必须设置授权头。该值的构造如下所述:

我正在用Python实现这一点,如下所示:

def get_authorisation_token(verb, resource_type, resource_id, date, master_key):
     key = base64.b64decode(master_key)

     text = f"""{verb.lower()}\n{resource_type.lower()}\n{resource_id.lower()}\n{date.lower()}\n\n"""

     text_encoded = text.encode('utf-8')

     signature_hash = hmac.new(key, text_encoded, digestmod=hashlib.sha256).digest()
     signature = base64.b64encode(signature_hash).decode()

     key_type = 'master'
     version = '1.0'

     uri = f'type={key_type}&ver={version}&sig={signature}'
     uri_encoded = urllib.parse.quote(uri)

     return uri_encoded
由于每次调用都会发送此消息,因此需要重新创建身份验证令牌以匹配请求URL。因此,例如,要获取数据库列表,必须提供资源类型为
dbs
,资源链接/ID为空字符串,URL为:
https://{databaseaccount}.documents.azure.com/dbs/

我无法理解的部分是资源类型和资源ID/链接的正确组合,以从特定数据库获取所有用户。文档可在此处找到:

我尝试了一些组合,但没有返回用户,我只得到了401:

{
    "code": "Unauthorized",
    "message": "The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'get\nusers\ndbs/<db_name>\nmon, 09 nov 2020 23:37:24 gmt\n\n'\r\nActivityId: 697a4159-f160-4aab-ae90-6cb5eaadb710, Microsoft.Azure.Documents.Common/2.11.0"
}
{
“代码”:“未经授权”,
“信息”:“输入授权令牌无法为请求提供服务。请检查预期的负载是否按照协议生成,并检查正在使用的密钥。服务器使用以下负载进行签名:'get\nusers\ndbs/\nmon,09 nov 2020 23:37:24 gmt\n\n'\r\n活动ID:697a4159-f160-4aab-ae90-6cb5eaadb710,Microsoft.Azure.Documents.Common/2.11.0”
}

关于此问题,请参考以下代码

from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import base64
from urllib.parse import quote
import hmac
from hashlib import sha256
import requests
from azure.cosmos.auth import GetAuthorizationHeader
from azure.cosmos.cosmos_client import CosmosClientConnection

master_key = ''
database_name = ''
key = base64.b64decode(master_key)
verb = 'GET'
resource_type = 'users'
resource_id = f'dbs/{database_name}'
now = datetime.now()
stamp = mktime(now.timetuple())
date = format_date_time(stamp)
print(date)
text = "{verb}\n{resource_type}\n{resource_id}\n{date}\n{other}\n".format(
    verb=(verb.lower() or ''),
    resource_type=(resource_type.lower() or ""),
    resource_id=(resource_id or ""),
    date=date.lower(),
    other="".lower())

body = text.encode("utf-8")
digest = hmac.new(key, body, sha256).digest()
signature = base64.encodebytes(digest).decode("utf-8")
key_type = 'master'
version = '1.0'
uri = f'type={key_type}&ver={version}&sig={signature[:-1]}'
uri_encoded = quote(uri)

url = "https://<>.documents.azure.com:443/dbs/<>/users"

payload = {}
headers = {
    'Authorization': uri_encoded,
    'x-ms-date': date,
    'x-ms-version': '2018-12-31'
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

从wsgiref.handlers导入格式\u日期\u时间
从日期时间导入日期时间
自始至终
导入base64
从urllib.parse导入引号
进口hmac
从hashlib导入sha256
导入请求
从azure.cosmos.auth导入GetAuthorizationHeader
从azure.cosmos.cosmos_客户端导入CosmosClientConnection
主密钥=“”
数据库名称=“”
key=base64.b64解码(主密钥)
动词='GET'
资源类型='用户'
resource_id=f'dbs/{database_name}'
now=datetime.now()
stamp=mktime(now.timetuple())
日期=格式\日期\时间(戳记)
打印(日期)
text=“{verb}\n{resource\u type}\n{resource\u id}\n{date}\n{other}\n”。格式(
动词=(动词.lower()或“”),
资源类型=(资源类型.lower()或“”),
资源id=(资源id或“”),
日期=日期。下限(),
其他=“.lower())
正文=文本编码(“utf-8”)
digest=hmac.new(key,body,sha256).digest()
签名=base64.encodebytes(摘要)。解码(“utf-8”)
键类型='master'
版本='1.0'
uri=f'type={key_type}&ver={version}&sig={signature[:-1]}'
uri_encoded=quote(uri)
url=”https://.documents.azure.com:443/dbs//users"
有效载荷={}
标题={
“授权”:uri_编码,
“x-ms-date”:日期,
“x-ms-version”:“2018-12-31”
}
response=requests.request(“GET”,url,headers=headers,data=payload)
打印(response.text)

资源类型应为
users
,资源链接应为
dbs/{}
我尝试了资源类型为
users
和链接为
dbs/db_name
,但仍然不起作用。返回了与上面相同的错误OK。我明白了。我会做一个测试。如果它对你有用,你可以吗?谢谢@Jim的帮助,这确实解决了问题。我的代码中的resourceType和resourceId不正确。