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: