Azure cosmos db проблемы с подключением по токену ресурса - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь подключиться к своей базе данных cosmos db, используя Resource token вместо учетной записи master key, которую я использовал ранее.Ранее я использовал следующий способ создания DocumentClient:

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

. Этот способ хорошо работает, но я хочу использовать resource token способов для этой цели, как упомянуто в этих статьях: link1 и link2 .

Я создал db user с 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 .

Первая и третья ошибки являются самыми странными, потому что я проверил и вижу значение ResourceId в переменной perm (как элемент permList коллекция), а также в переменной permissions из первой версии.

Может кто-нибудь помочь с этим?

UPDATE Я проверил 4-йверсия, которая дает мне тот же результат, что и попытка 1,3: Не удалось проанализировать значение '' как ResourceId., documentdb-dotnet-sdk / 1.22.0 Host / 32-bit 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;
    }

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

У меня есть похожий случай, когда в моей модели я использую разбиение.Итак, я разработал эту функцию, чтобы получить токен пользователя.

    private async Task<string> GetUserToken()
    {
        User user = null;
        try
        {
            try
            {
                var uri = UriFactory.CreateUserUri(config.Database, config.PartitionKey);
                client.DeleteUserAsync(uri).Wait();

                user = await client.ReadUserAsync(UriFactory.CreateUserUri(config.Database, config.PartitionKey));

                var permission = await GetorCreatePermission(user, config.Collection, config.PartitionKey);
                return permission.Token;
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);
            }
            if (user == null)
            {
                user = new User
                {
                    Id = config.PartitionKey
                };
                user = await client.CreateUserAsync(UriFactory.CreateDatabaseUri(config.Database), user);
                var permission = await GetorCreatePermission(user, config.Collection, config.PartitionKey);
                return permission.Token;
            }
            else
            {
                throw new Exception("");
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
0 голосов
/ 18 мая 2018

Маркер ресурса Cosmos DB будет сгенерирован при создании разрешения.Мы можем использовать жетон ресурса для подключения к базе данных Cosmos, как показано ниже:

var client = new DocumentClient(new Uri(endPointUri), resourceToken );

И мы можем получить жетон ресурса разрешения, как показано ниже:

    public static async Task<Dictionary<PermissionMode, string>> GetPermissonTokens(DocumentClient client,string DatabaseId,string userId)
    {
        FeedResponse<Permission> permFeed =  await client.ReadPermissionFeedAsync(UriFactory.CreateUserUri(DatabaseId, userId));

        Dictionary<PermissionMode,string> permList = new Dictionary<PermissionMode, string>();

        foreach (Permission perm in permFeed)
        {

            permList.Add(perm.PermissionMode, perm.Token);
        }

        return permList;
    }

Вот полная демонстрация для вашегоссылка:

    static void Main(string[] args)
    {
        //create DocumentClient instance with end point Uri and primary key
        DocumentClient client = new DocumentClient(new Uri("https://xxxx.xxxxx.azure.com:443/"), "ikhSrMZIGKBrF1xxxxx7iDSLBMJD37oCOlw2N24YoBtfAV7HJFfVgNbhCfQdWGAq3eZY4FyX3z6zsWoRLHQ==", new ConnectionPolicy { EnableEndpointDiscovery = false });

        Task<Dictionary<PermissionMode, string>> task = GetPermissonTokens(client, "Test2", "testUser2");
        task.Wait();
        Dictionary<PermissionMode, string> permissionTokens = task.Result;

        DocumentClient userClient = new DocumentClient(client.ReadEndpoint, permissionTokens[PermissionMode.All]);
        if (userClient != null)
        {
            //then we can do CRUD operation to Cosmos DB Here 
        }
    }


    public static async Task<Dictionary<PermissionMode, string>> GetPermissonTokens(DocumentClient client,string DatabaseId,string userId)
    {
        FeedResponse<Permission> permFeed =  await client.ReadPermissionFeedAsync(UriFactory.CreateUserUri(DatabaseId, userId));

        Dictionary<PermissionMode,string> permList = new Dictionary<PermissionMode, string>();

        foreach (Permission perm in permFeed)
        {

            permList.Add(perm.PermissionMode, perm.Token);
        }

        return permList;
    }
...