我使用的是 .NET Core,因此无法使用 Azure DocumentDb SDK。这就是为什么我想通过 REST 接口(interface)创建文档。我已设法查询数据库,但当我发布 JSON 文档时,我收到未经授权的响应。这是我的代码:
const string DatabaseId = "DB-id";
const string CollectionId = "UserSettings";
var documentDbUrl = "Injected via DI";
var authorizationKey = "Also injected;
using (var httpClient = new HttpClient())
{
var utcNow = DateTime.UtcNow;
httpClient.DefaultRequestHeaders.Add("x-ms-date", utcNow.ToString("r"));
httpClient.DefaultRequestHeaders.Add("x-ms-version", "2015-08-06");
httpClient.DefaultRequestHeaders.Add("x-ms-documentdb-is-upsert", "true");
var resourceLink = string.Format("dbs/{0}/colls/{1}/docs", DatabaseId, CollectionId);
var baseUrl = new Uri(documentDbUrl);
var masterKeyAuthorizationSignatureGenerator = new MasterKeyAuthorizationSignatureGenerator();
var authHeader = masterKeyAuthorizationSignatureGenerator.Generate("POST", resourceLink, "docs", authorizationKey, "master", "1.0", utcNow);
httpClient.DefaultRequestHeaders.Add("authorization", authHeader);
var response = await httpClient.PostAsJsonAsync(new Uri(baseUrl, resourceLink), userSettings);
// at this point, response.StatusCode is Unauthorized
}
您看到的MasterKeyAuthorizationSignatureGenerator
包含the logic to create the hash ,在查询数据库时有效:
public string Generate(string verb, string resourceId, string resourceType, string key, string keyType, string tokenVersion, DateTime requestDateTime)
{
var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
var payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",
verb.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
resourceId,
requestDateTime.ToString("r").ToLowerInvariant(),
""
);
var hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
var signature = Convert.ToBase64String(hashPayLoad);
return WebUtility.UrlEncode(string.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
keyType,
tokenVersion,
signature));
}
我确信databaseid、collectionid、url 和key 是正确的。 key 和 id 与我用来查询的相同,有效。当我更改 url 时,例如通过添加 documentid(然后我自己生成),我会收到另一条消息 (MethodNotAllowed)。
更新:
使用 Postman,我可以看到这是我得到的响应:
{
"code": "Unauthorized",
"message": "The input authorization token can't serve the request.
Please check that the expected payload is built as per the
protocol, and check the key being used. Server used the
following payload to sign:
'post\ndocs\ndbs/MyDb/colls/MyColl\nsat, 23 apr 2016 09:44:39 gmt\n\n'\r\nActivityId: 1be76530-ad32-4b54-b96b-6e0d4ebbc851"
}
关于我做错了什么或者我如何分析这个问题有任何提示吗?
最佳答案
请注意,有两种方法可以在 URI 中指定资源:
1) using the resource id. The id is user settable.
2) using the resource _rid. This is the system generated id for the resource.
使用资源 ID(方法 1)时,必须确保用于散列签名 token 的连接 token 中的资源 ID 与资源中使用的大小写相同,因为资源 ID 区分大小写。例如,如果集合的资源 id 是 MyCollection,则资源 id 应该恰好是串联 token 中的 MyCollection。
本文提供了构建哈希签名 token 的更多详细信息。 https://msdn.microsoft.com/en-us/library/azure/dn783368.aspx
关于.net - 通过 REST 在 DocumentDb 中创建文档时未经授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36752148/