I'm trying to connect to my cosmos db database by using a Resource token instead of a account master key which I used before.
Before I used the following way to create DocumentClient:
var client = new DocumentClient(new Uri(configAccountName), configAccountKey);
await client.OpenAsync();
This way works well, but I want to use resource token ways for that target as mentioned in these articles : link1 and link2.
I've created a db user with All permissions by the following code:
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;
}
The user is created correctly and I can retrieve him by ReadUserAsync or his permissions by ReadPermissionAsync methods.
Then, I want to create new instance of DocumentClient with permissions of newly created user.
//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);
I've checked 3 ways (some of them are similar). I've tryied to call each of ways to get new DocumentClient instance(newClient variable) and then call OpenAsync method to open connection:
var newClient = await client.GetClientForUserAsync_v###(userName);
await newClient.OpenAsync();
All tryings were failed
//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);
}
The OpenAsync method was crashed with this error : Failed to parse the value '' as 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);
}
The OpenAsync method was crashed with this error : Insufficient permissions provided in the authorization header for the corresponding request. Please retry with another authorization header.
ActivityId: ##ReplacedActivityId##, Microsoft.Azure.Documents.Common/1.22.0.0, documentdb-dotnet-sdk/1.22.0 Host/32-bit 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;
}
The OpenAsync method was crashed with this error : Failed to parse the value '' as ResourceId., documentdb-dotnet-sdk/1.22.0 Host/32-bit MicrosoftWindowsNT/6.2.9200.0.
The first and third errors are the most strange, because I've checked and I see the ResourceId value in the perm variable (as item of permList collection) as well as in permissions variable from the first version.
Could anyone help with it?
UPDATE I've checked the 4th version, which gives me the same result as 1,3 trying: Failed to parse the value '' as 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;
}
The Cosmos DB resource token will be generated when the permission been built. We can use resource token to connect to Cosmos DB like below:
And we can get resource Token of the permission as below:
Here is a Complete demo for your reference: