首页 > 解决方案 > Azure cosmos db 的资源令牌连接问题

问题描述

我正在尝试cosmos db使用 a而不是我以前使用Resource token的帐户连接到我的数据库。master key在我使用以下方式创建之前DocumentClient

    var client = new DocumentClient(new Uri(configAccountName), configAccountKey);
    await client.OpenAsync();

这种方法效果很好,但我想使用resource token这些文章中提到的方法来实现该目标:link1link2

我通过以下代码创建了一个db userwith :All permissions

    public static async Task<User> CreateUserAndPermissionAsync(this DocumentClient client, string userId)
    {
        var dbUri = UriFactory.CreateDatabaseUri(dataBase);
        var user = await client.CreateUserAsync(dbUri, new User { Id = userId });
        var collectionUri = UriFactory.CreateDocumentCollectionUri(dataBase, collectionName);
        var permission = await client.CreatePermissionAsync(
            user.Resource.SelfLink,
            new Permission
            {
                Id = "MyPermission",
                PermissionMode = PermissionMode.All,
                ResourceLink = collectionUri.ToString(),
                ResourcePartitionKey = new PartitionKey(userId)
            });
        return user.Resource;
    }

用户已正确创建,我可以通过方法检索他ReadUserAsync或他的权限ReadPermissionAsync。然后,我想创建新创建用户的DocumentClient新实例。permissions

    //this is a temporally document client instance to read permissions for my user in below extensions method versions
    var client = new DocumentClient(new Uri(configAccountName), configAccountKey);

我检查了 3 种方法(其中一些是相似的)。我尝试调用每种方法来获取新DocumentClient实例(newClient变量),然后调用OpenAsync方法来打开连接:

    var newClient = await client.GetClientForUserAsync_v###(userName);
    await newClient.OpenAsync();

所有的尝试都失败了

    //version 1:
    public static async Task<DocumentClient> GetClientForUserAsync_v1(this DocumentClient client, string userId)
    {
        var userUri = UriFactory.CreateUserUri(dataBase, userId).ToString();
        var permissionsUri = $"{userUri}/permissions";
        var permissions = (await client.ReadPermissionFeedAsync(permissionsUri)).ToList();
        return new DocumentClient(
            client.ServiceEndpoint,
            permissions,
            client.ConnectionPolicy);
    }

OpenAsync方法因以下错误而崩溃:无法将值“解析为 ResourceId., documentdb-dotnet-sdk/1.22.0 Host/32-bit MicrosoftWindowsNT/6.2.9200.0

    //version 2:
    public static async Task<DocumentClient> GetClientForUserAsync_v2(this DocumentClient client, string userId)
    {
        var userUri = UriFactory.CreateUserUri(dataBase, userId).ToString();
        var permissionsUri = $"{userUri}/permissions";
        var permissions = (await client.ReadPermissionFeedAsync(permissionsUri)).ToList();
        return new DocumentClient(
            client.ServiceEndpoint,
            permissions[0].Token,
            client.ConnectionPolicy);
    }

OpenAsync方法因以下错误而崩溃:相应请求的授权标头中提供的权限不足。请使用另一个授权标头重试。ActivityId:##ReplacedActivityId##,Microsoft.Azure.Documents.Common/1.22.0.0,documentdb-dotnet-sdk/1.22.0 主机/32 位 MicrosoftWindowsNT/6.2.9200.0

    //version 3:
    public static async Task<DocumentClient> GetClientForUserAsync_v3(this DocumentClient client, string userId)
    {
        FeedResponse<Permission> permFeed = await client.ReadPermissionFeedAsync(UriFactory.CreateUserUri(dataBase, userId));
        List<Permission> permList = new List<Permission>();

        foreach (Permission perm in permFeed)
        {
            permList.Add(perm);
        }

        DocumentClient userClient = new DocumentClient(new Uri(client.ServiceEndpoint.AbsoluteUri), permList, new ConnectionPolicy()
        {
            //**UPDATE**: I tried all ConnectionMode values as well as without this parameter
            ConnectionMode = ConnectionMode.Gateway
        });
        return userClient;
    }     

OpenAsync方法因以下错误而崩溃:无法将值“解析为 ResourceId., documentdb-dotnet-sdk/1.22.0 Host/32-bit MicrosoftWindowsNT/6.2.9200.0

第一个和第三个错误是最奇怪的,因为我已经检查并看到permResourceId变量(作为permList集合的项目)以及第一个版本的权限变量中的值。

有人可以帮忙吗?

更新 我已经检查了第 4 个版本,这给了我与 1,3 尝试相同的结果:无法将值 '' 解析为 ResourceId。,documentdb-dotnet-sdk/1.22.0 主机/32 位 MicrosoftWindowsNT/6.2。 9200.0

    //version 4
    public static async Task<DocumentClient> GetClientForUserAsync_v4(this DocumentClient client, string userId)
    {
        var user = await client.ReadUserAsync(UriFactory.CreateUserUri(dataBase, userId));
        var permissions = await client.ReadPermissionFeedAsync(user.Resource.SelfLink);
        List<Permission> permList = new List<Permission>();

        foreach (Permission perm in permissions)
        {
            permList.Add(perm);
        }

        DocumentClient userClient = new DocumentClient(new Uri(client.ServiceEndpoint.AbsoluteUri), permList, new ConnectionPolicy()
        {
            ConnectionMode = ConnectionMode.Direct
        });
        return userClient;
    }

标签: permissionsazure-cosmosdbresource-iddocumentclient

解决方案


经过多次尝试,我最终得出的一个结论是在为集合创建权限时不包含 PartitionKey。下面的调整为我完成了这项工作,我能够使用资源令牌成功地将内容添加到我的收藏中。

    new Permission
    {
        Id = "MyPermission",
        PermissionMode = PermissionMode.All,
        ResourceLink = collectionUri.ToString()
    });

推荐阅读