Share via


Azure API Gateway Policy Set Query

Question

Wednesday, December 20, 2017 5:59 AM

I would like to add query parameter for the request by using response from my auth service. These are the example:

<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>

But I am getting this error:

{
    "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."
    ]
}

Any idea how should I do it ?

By getting decoded JWT from my AUTH service and added it to the request to backend

Thank You

Adityo Setyonugroho

All replies (6)

Wednesday, December 20, 2017 11:09 PM âś…Answered

You only get one pass at the response body. In your original policy we have access to it in the <when> condition attribute, but we attempt to set the value of your <set-query-parameter> the Body object is null and we throw that error.

You will want to store that response body in a local variable and then check properties as needed. See if this works: 

 

<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>

 

**   <set-variable name="resbody" value="@(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>())"/>**

 

  <choose>

**    <when condition="@((bool)((JObject)context.Variables["resbody"])["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)((JObject)context.Variables["resbody"])["content"]["domain_id"])**

            </value>

        </set-query-parameter> 

    </otherwise>

  </choose>

 

  <base />

 

</inbound>

</policies>

 

hth

-Todd

Microsoft Distributed Services Support


Wednesday, December 20, 2017 7:14 AM

I would suggest you verify the context.Variables["tokenstate"] value is null or not and let us know if you need further assistance.

Do click on "Mark as Answer" on the post that helps you, this can be beneficial to other community members.


Wednesday, December 20, 2017 8:02 AM

Hi,

Thank you for your response.

context.Variables["tokenstate"] is not null.

It has been verified on condition method.

When I tried to use context.Variables["tokenstate"].StatusCode , it works and send me a query 200.

Do I need to do something on using Object in policy ? 

Adityo Setyonugroho


Tuesday, December 26, 2017 4:19 AM

Hi,

Thank you Todd for your answer.

Now, I can use it as variable and use it any time.

Adityo Setyonugroho


Wednesday, June 5, 2019 8:21 AM

Hi,

It does not solve my issue. I added same structure of code in my APIM but i get following error:Can you please helpme?

set-variable (1.227 ms)
{
    "messages": [
        {
            "message": "Expression evaluation failed.",
            "expression": "((IResponse)context.Variables[\"tokenstate\"]).Body.As<JObject>()",
            "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."
    ]
}

Friday, June 14, 2019 2:15 AM

@GeniusND , can you share your full structure ?

Adityo Setyonugroho