401通过Azure APIM发送请求调用Cosmos DB API时未经授权

vnjpjtjt  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(79)

当通过APIM send-request频繁调用CosmosDB API时,有时我会得到401 Unauthorized,有时会得到200,这是我所期望的。我尝试生成相同的请求并使用Postman频繁发送,所有时间的响应都是200。
下面是APIM策略代码片段:

<set-variable name="currentDate" value="@(DateTime.UtcNow.ToString("r"))" />
    <set-variable name="userMetadataCosmosDBKey" value="{{UserMetadataCosmosDBKey}}" />
    <set-variable name="userMetadataCosmosDBUri" value="{{UserMetadataCosmosDBUri}}" />
    <set-variable name="userMetadataResourceId" value="{{UserMetadataResourceId}}" />
    <set-variable name="token" value="@{
      var verb = "POST";
      var resourceType = "docs";
      var resourceId = (string)context.Variables["userMetadataResourceId"];
      var date = (string)context.Variables["currentDate"];
      var key = (string)context.Variables["userMetadataCosmosDBKey"];
      var keyType = "master";
      var tokenVersion = "1.0";
      var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
      verb = verb ?? "";
      resourceType = resourceType ?? "";
      resourceId = resourceId ?? "";
      string payLoad = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n",
      verb.ToLowerInvariant(),
      resourceType.ToLowerInvariant(),
      resourceId,
      date.ToLowerInvariant(),
      "");
      byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
      string signature = Convert.ToBase64String(hashPayLoad);
      return String.Format("type={0}&ver={1}&sig={2}",
        keyType,
        tokenVersion,
        signature);        
     }" />
    <send-request mode="new" response-variable-name="userMetadataResponse" timeout="20" ignore-error="false">
        <set-url>@(new Uri(string.Format("{0}{1}/docs",(string)context.Variables["userMetadataCosmosDBUri"],(string)context.Variables["userMetadataResourceId"])).ToString())</set-url>
        <set-method>POST</set-method>
        <set-header name="x-ms-documentdb-isquery" exists-action="override">
            <value>true</value>
        </set-header>
        <set-header name="Content-Type" exists-action="override">
            <value>application/query+json</value>
        </set-header>
        <set-header name="x-ms-version" exists-action="override">
            <value>2017-02-22</value>
        </set-header>
        <set-header name="x-ms-date" exists-action="override">
            <value>@((string)context.Variables["currentDate"])</value>
        </set-header>
        <set-header name="x-ms-query-enable-crosspartition" exists-action="override">
            <value>true</value>
        </set-header>
        <set-header name="Authorization" exists-action="override">
            <value>@((string)context.Variables["token"])</value>
        </set-header>
        <set-body>@{  
                        return new JObject(  
                            new JProperty("query","SELECT * FROM c WHERE c.APIMUserId=@apiUserId"),  
                            new JProperty("parameters", 
                                new JArray(
                                    new JObject(  
                                        new JProperty("name","@apiUserId"),  
                                        new JProperty("value", context.User.Id)
                                        )
                                    )
                                )
                            ).ToString();  
                    }</set-body>
    </send-request>
    <!-- Store response body in userMetadata variable -->
    <set-variable name="userMetadata" value="
      @{
         var response = ((IResponse)context.Variables["userMetadataResponse"]).Body.As<JObject>(true);                                                                                                                                                                                                           
         var metadata = response["_count"].ToString() == "1" ? response["Documents"][0] : new JObject();                                                                                                                                                                                                                                                
         return metadata;                                                                                                                                                                                                                                                
       }" />

字符串
第401章为什么有时候会有

6fe3ivhb

6fe3ivhb1#

通过将System.Uri.EscapeDataString()添加到返回的token来使其工作:

System.Uri.EscapeDataString(String.Format("type={0}&ver={1}&sig={2}",
                                    keyType,
                                    tokenVersion,
                                    signature));

字符串

ac1kyiln

ac1kyiln2#

您还可以使用

<authentication-managed-identity 
    resource="https://cosmon-samples-234f1f22a3.documents.azure.com" 
    output-token-variable-name="msi-access-token" 
    ignore-error="false" />

<set-header name="Authorization" exists-action="override">
    <value>@("type=aad&ver=1.0&sig=" + context.Variables["msi-access-token"])</value>
</set-header>

字符串
对向CosmosDB发出的APIM请求进行身份验证。请确保您已在CosmosDB RBAC https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac中授予权限
完整的样本与所有的细节可以在我的文章https://byalexblog.net/article/azure-apimanagement-to-azure-cosmosdb/中找到

相关问题