我尝试使用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
方法因此错误而崩溃:无法解析值&#39;&#39; 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);
}
OpenAsync
方法因此错误而崩溃:相应请求的授权标头中提供的权限不足。请使用其他授权标头重试。
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;
}
OpenAsync
方法因此错误而崩溃:无法解析值&#39;&#39; as ResourceId。,documentdb-dotnet-sdk / 1.22.0 Host / 32-bit MicrosoftWindowsNT / 6.2.9200.0 。
第一个和第三个错误最奇怪,因为我已经检查过,我在 perm 变量中看到ResourceId
值(作为 permList <的项目< / em> collection)以及第一版中的 permissions 变量。
有人可以帮忙吗?
更新 我检查了第4个版本,它给出了与1,3尝试相同的结果:无法解析值&#39;&#39; 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;
}
答案 0 :(得分:0)
构建权限时将生成Cosmos DB资源令牌。我们可以使用资源令牌连接到Cosmos DB,如下所示:
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;
}
答案 1 :(得分:0)
我有类似的情况,在我的模型中我正在使用分区。因此,我开发了此功能来获取用户令牌。
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;
}
}
答案 2 :(得分:0)
经过多次尝试,我最后得出的一个结论是在创建集合许可时不包括PartitionKey。下面的调整为我完成了这项工作,并且我能够使用资源令牌将内容成功添加到我的收藏中。
new Permission
{
Id = "MyPermission",
PermissionMode = PermissionMode.All,
ResourceLink = collectionUri.ToString()
});