Azure API网关策略

问题描述 投票:0回答:1

我想通过使用来自我的auth服务的响应为请求添加查询参数。这些是例子:

<policies>
    <inbound>
  <!-- Extract Token from Authorization header parameter -->
  <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","JWT").Split(' ').Last())" />

  <!-- Send request to Token Server to validate token (see RFC 7662) -->
  <send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="false">
    <set-url>AUTH Service</set-url>
    <set-method>POST</set-method>
    <set-header name="Content-Type" exists-action="override">
      <value>application/x-www-form-urlencoded</value>
    </set-header>
    <set-body>@($"token={(string)context.Variables["token"]}")</set-body>
  </send-request>

  <choose>
    <when condition="@((bool)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["active"] == false)">
      <return-response response-variable-name="existing response variable">
      <set-status code="401" reason="Unauthorized" />
      </return-response>

    </when>
    <otherwise>  
        <set-query-parameter name="domain_id" exists-action="append">  
            <value>
            @((string)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["content"]["domain_id"])
            </value>
        </set-query-parameter>  
    </otherwise> 
  </choose>

  <base />

</inbound>
</policies>

但是我收到了这个错误:

{
    "messages": [
        {
            "message": "Expression evaluation failed.",
            "expression": "(string)((IResponse)context.Variables[\"tokenstate\"]).Body.As<JObject>()[\"content\"]",
            "details": "Object reference not set to an instance of an object."
        },
        "Expression evaluation failed. Object reference not set to an instance of an object.",
        "Object reference not set to an instance of an object."
    ]
}

知道我应该怎么做?

通过从我的AUTH服务获取解码的JWT并将其添加到后端请求中

谢谢

azure-api-management
1个回答
1
投票

出于性能原因,APIM服务总是避免在内存中缓存完整的请求/响应主体,因此当您调用((IResponse)context.Variables [“tokenstate”])。Body.As()响应直接从auth服务器流式传输并且同时时间转换为JObject,因此在此之后消耗,第二次调用.Body.As()将产生空值。

为避免这种情况,您有两种选择:

  1. 调用((IResponse)context.Variables["tokenstate"]).Body.As<JObject>(true) - 此附加参数指示服务在内存中缓存响应,以便将其保留以供以后检查。但是稍后再次使用.As()调用将再一次将原始响应解析为JSON再次执行相同的工作并且是性能损失。
  2. 或做<set-variable name="tokenstate" value="((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()" />。这将使用已解析的JSON主体覆盖tokenstate变量的值,该主体可以在以后多次使用,因为它现在将存储在内存中。
© www.soinside.com 2019 - 2024. All rights reserved.