首页 > 解决方案 > 授权标头未确认为所需格式 - Python Cosmos-db api

问题描述

我正在使用 python cosmos-db 库来:创建数据库、容器和用户。

azure cosmos 实例正在本地运行。

使用主密钥,我可以成功创建数据库、容器和用户。

但是,一旦我有了一个用户并生成了令牌,当我尝试查询数据库时,我就会收到以下错误:

授权标头未确认为所需的格式。请验证并重试。

我曾尝试从 Microsoft 执行整个示例代码,但它会引发相同的错误。示例代码可以在这里找到:https ://github.com/Azure/azure-sdk-for-python/blob/4f96d8a8dfde9b4cac9d2103b5f58d5705b26ded/sdk/cosmos/azure-cosmos/samples/access_cosmos_with_resource_token.py

这是用于打开令牌客户端和查询集合的代码片段。

def run_sample():
    client = cosmos_client.CosmosClient(HOST, {"masterKey": MASTER_KEY})
#</configureConnectivity>


    try:
        try:
            db = client.create_database(DATABASE_ID)
        except exceptions.CosmosResourceExistsError:
            db = client.get_database_client(DATABASE_ID)

        try:
            container = db.create_container(
                id=CONTAINER_ID, partition_key=PARTITION_KEY
            )
        except exceptions.CosmosResourceExistsError:
            container = db.get_container_client(CONTAINER_ID)

        user = create_user_if_not_exists(db, USERNAME)

        # Permission to perform operations on all items inside a container
        permission_definition = {
            "id": CONTAINER_ALL_PERMISSION,
            "permissionMode": documents.PermissionMode.All,
            "resource": container.container_link,
        }

        permission = create_permission_if_not_exists(user, permission_definition)
        token = {}
        token[container.id] = permission.properties["_token"]

        # Use token to connect to database
        token_client = cosmos_client.CosmosClient(HOST, token)
        token_db = token_client.get_database_client(DATABASE_ID)
        token_container = token_db.get_container_client(CONTAINER_ID)

       # Query for items in a certain partition
        token_client_query(token_container, USERNAME_2)


def token_client_query(container, username):
    try:
        for item in container.query_items(
            query="SELECT * FROM my_container c WHERE c.username=@username",
            parameters=[{"name": "@username", "value": username}],
            partition_key=username,
        ):
            print(json.dumps(item, indent=True))
    except exceptions.CosmosHttpResponseError:
        print("Error in querying item(s)")

由此,我收到 401 响应。关于如何解决这个问题的任何想法?

标签: pythonazure-functionsazure-cosmosdb

解决方案


如上述评论所述,问题在于令牌的格式。

授权字符串应该在添加到 REST 请求之前进行编码,以确保它不包含无效字符。确保它是使用 MIME RFC2045 进行 Base64 编码的。

Azure Cosmos DB SQL API 中的访问控制

由此,我使用 urllib 库对令牌进行编码并将其传递给解决了问题的 http 请求,因为响应是所需的文档。

import urllib.parse   
urllib.parse.quote_plus(token[container.id])

推荐阅读