我正在尝试构建代理 API 管理并添加此策略。我总是收到HTTP/1.1 401未经授权的
<policies>
<inbound>
<base />
<set-variable name="cosmoskey" value="{{CosmosKey}}" />
<set-variable name="requestDateString" value="@(DateTime.UtcNow.ToString("r"))" />
<send-request mode="new" response-variable-name="response" timeout="10" ignore-error="false">
<set-url>https://fellowtest.documents.azure.com/dbs/ToDoList/colls/Items/docs</set-url>
<set-method>POST</set-method>
<set-header name="Authorization" exists-action="override">
<value>@{
var verb = "GET";
var resourceType = "docs";
var resourceLink = "";
var key = context.Variables.GetValueOrDefault<string>("cosmoskey");
var keyType = "master";
var tokenVersion = "1.0";
var date = context.Variables.GetValueOrDefault<string>("requestDateString");
var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
verb = verb ?? "";
resourceType = resourceType ?? "";
resourceLink = resourceLink ?? "";
string payLoad = string.Format("{0}n{1}n{2}n{3}n{4}n",
verb.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
resourceLink,
date.ToLowerInvariant(),
""
);
byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
string signature = Convert.ToBase64String(hashPayLoad);
return System.Uri.EscapeDataString(String.Format("type={0}&ver={1}&sig={2}",
keyType,
tokenVersion,
signature));
}</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>application/json</value>
</set-header>
<set-header name="x-ms-date" exists-action="override">
<value>@(context.Variables.GetValueOrDefault<string>("requestDateString"))</value>
</set-header>
<set-header name="x-ms-version" exists-action="override">
<value>2016-07-11</value>
</set-header>
</send-request>
</inbound>
当我从邮递员那里做同样的事情时,它可以工作,但不能通过 API 管理
HTTP/1.1 401 Unauthorized
strict-transport-security: max-age=31536000
x-ms-gatewayversion: version=2.1.0.0
date: Tue, 16 Oct 2018 10:31:14 GMT
vary: Origin
ocp-apim-trace-location: https://apimgmtstpf0fn54oijkfxdy.blob.core.windows.net/apiinspectorcontainer/ZwM6kv46nxmT68jcPQD2Cw2-80?sv=2017-04-17&sr=b&sig=vxLvbzC6eGFtdo2tGN8XcmGgOq7Dtpv4QUBVoRt7L7g%3D&se=2018-10-17T10%3A31%3A14Z&sp=r&traceId=d330a86fe0334c99ad36fbc5ea737c00
content-type: application/json
x-ms-activity-id: 43409a3d-06a7-4d2c-8e41-a5d8bc1456e7
transfer-encoding: chunked
content-location: https://fellowtest.documents.azure.com/test3
{
"code": "Unauthorized",
"message": "Required Header authorization is missing. Ensure a valid Authorization token is passed.rnActivityId: 43409a3d-06a7-4d2c-8e41-a5d8bc1456e7, Microsoft.Azure.Documents.Common/2.1.0.0"
}
跟踪看起来不错,所以我找不到错误在哪里。有没有人做过或知道我在哪里可以找到操作方法?
要构造有效的散列令牌签名(有关详细信息,请参阅 https://learn.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources(,您需要提供 Verb(在您的情况下为 "get" - 没关系,因为它是 GET 请求(、ResourceType("docs" - 没关系,因为您想列出文档(和ResourceLink(在您的情况下是它的"(,在您的情况下,应设置为:
var resourceLink = "dbs/ToDoList/colls/Items";
此外,发送请求策略不会向调用方返回响应。基本上,将响应保存为参数给出的变量(在本例中为"响应"(。
<发送请求模式 响应变量名称="响应" 超时="10" 忽略错误="假">发送请求模式>
若要将响应返回给调用方,可以使用<返回响应>策略。返回响应>
<return-response>
<set-body>@(((IResponse)context.Variables["response"]).Body.As<JObject>(preserveContent: true).ToString())</set-body>
</return-response>
评论中提到的解决方案似乎是实现您想要做的事情的最佳解决方案(https://www.fellow-consulting.com/azure-api-management-proxy-to-cosmos-db/(