Cosmosdb Resource Token Authorization Header using a REST call

时间:2018-11-16 21:44:19

标签: azure-cosmosdb

Cosmosdb has the concept of a permission for a user. That permission contains a token that can be used to access a specified partition for a limited time with limited access.

I've created a resource token broker, which creates the permission, retrieves the token and returns it to a client Xamarin Forms app. So far so good.

If I am using the DocumentClient from the .NET SDK, that token - unmodified - works great.

However, I'd like to avoid having a dependency on DocumentClient in my app and just instead make REST api calls directly to Cosmosdb.

If I put that token in the authorization header, I get format errors for that header. I can't find the source code to the SDK, and all the samples are built modifying a master token.

Can anyone explain/point/sample me on what I have to do to that resource token that I get from the permission to make it an acceptable header so I can just make a REST call?

TIA

2 个答案:

答案 0 :(得分:1)

根据您的描述,我认为您已经知道如何获取资源令牌。除了资源令牌格式,您的所有工作都很好。您需要urlencode资源令牌,然后您的代码才能正常运行。我测试成功了。

var databaseId = "db";
var collectionId = "coll";
var datetime = DateTime.UtcNow.ToString("R");
var version = "2017-02-22";
var resourceId = $"dbs/{databaseId}/colls/{collectionId}";
var auth = "type%3Dresource%26ver%3D1%26sig%3Dny%2BUlL6QIWR69OfiaSjTsw%3D%3D%3B%2Ba%2FwmK37zLn%2FoilfztnXpfyCN3n9tChunmpBdROF8BH4**********************oU0BJ4z8aDZT%2F%2FgTVJ0hgpXTK8UYMOrL5di3he9wbvQwFkFOdpXD7%2B%2Byhmb1uUOnq%2Fyp454O2fQKR8uA3KaiLCCjYZ6qr%2BQ%2BTV1Cu1u%2F6Yj34nc4UYtpRBX5K************qCGjhvpQ%3D%3D%3B";

var urlPath = $"https://***.documents.azure.com/dbs/db/colls/coll/docs/1";
Uri uri = new Uri(urlPath);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpClient client = new HttpClient();

client.DefaultRequestHeaders.Add("x-ms-date", datetime);
client.DefaultRequestHeaders.Add("x-ms-version", version);   
client.DefaultRequestHeaders.Add("Authorization", auth);
HttpResponseMessage response = client.SendAsync(request).Result;
var status = response.IsSuccessStatusCode;
var message = response.RequestMessage;

答案 1 :(得分:1)

杰伊的解决方案是正确的。我缺少几个部分。此项适用于任何面对相同事情的可怜魔鬼。

  1. 正如Jay指出的那样,权限对象中实际上从Cosmosdb返回的令牌未编码。从.Net Core 2.x开始,您需要使用WebUtility.UrlEncode(token)来以正确的格式获取它。我花了一个小时而不是HtmlEncode使用UrlEncode。我是个白痴。

{更新:我比原来的想法还要愚蠢。您必须使用HttpUtility.UrlEncode,而不是WebUtility.UrlEncode。这是因为它们的编码方式不同。 WebUtility的结尾类似%3D,而HttpUtility对其进行了编码%3d。 无关紧要,除了认证令牌。当我在DocumentClient调用上运行Fiddler时,我注意到令牌包含小写的编码值。} 因此,忽略上面的#1并使用{{1 }}。

  1. 我提到我在最初的问题中使用分区,但是Jay的答案并未涵盖这一点,因此我仍然失败了。我正在指定分区键,但是从文档中尚不清楚是HttpUtility 路径还是partition key 。如果您认为权限令牌在创建时将包含权限键 value ,那并不是很明显。无法知道幕后情况。反复试验。我个人的最爱。
  2. 但是分区键的格式不太明显。如果将权限限制为分区,则需要在标头中指定分区,如下所示:

    partition key

  3. 您需要像这样设置client.DefaultRequestHeaders.Add("x-ms-documentdb-partitionkey", partitions);变量的格式:

    partitions

那是因为Cosmodb期望有string json = JsonConvert.SerializeObject(new[] { "b39bcd43-8d3d-*********-4e4492fa3e7d" }); 个分区键,即使它只接受列表中的分区键(如我所知)。如果您不想使用array,则可以使用JsonConvert手动进行构建。

毕竟它像桃子一样起作用。再次感谢杰伊!