Tuesday, October 1, 2024

APIM policy to get the token and send request in backend

   <backend>

        <retry condition="@(context.Response.StatusCode == 401)" count="2" interval="1" first-fast-retry="true">
            <choose>
                <when condition="@(context.Variables.GetValueOrDefault("calledOnce", false))">
                    <cache-remove-value key="token" />
                </when>
            </choose>
            <!-- Get token -->
            <cache-lookup-value key="token" default-value="noToken" variable-name="token" />
            <!-- Retrieve token if needed -->
            <choose>
                <when condition="@((string)context.Variables["token"] == "noToken")">
                    <set-variable name="clientSecret" value="@(System.Net.WebUtility.UrlEncode("{{concur-clientsecret}}"))" />
                    <!-- Retrieve token -->
                    <send-request ignore-error="false" timeout="20" response-variable-name="tokenResponse" mode="new">
                        <set-url>@($"{{concur-url}}/oauth2/v0/token")</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>@($"grant_type=refresh_token&client_id={{concur-clientid}}&client_secret={(string)context.Variables["clientSecret"]}&refresh_token={{concur-refresh-token}}")</set-body>
                    </send-request>
                    <!-- Cache token -->
                    <set-variable name="response" value="@(((IResponse)context.Variables["tokenResponse"]).Body.As<JObject>())" />
                    <set-variable name="token" value="@(((JObject)context.Variables["response"])["access_token"].ToString())" />
                    <set-variable name="duration" value="@(((JObject)context.Variables["response"])["expires_in"].ToString())" />
                    <cache-store-value key="token" value="@((string)context.Variables["token"])" duration="@(Int32.Parse((string)context.Variables["duration"]))" />
                </when>
            </choose>
            <!-- Use token for authorization
            <set-backend-service base-url="{{concur-url}}/api/v3.0/expense/reports?approvalStatusCode=A_APPR&amp;processingPaymentDateAfter=2024-09-10T04:59:33&amp;processingPaymentDateBefore=2024-10-01T10:57:37&amp;limit=100&amp;user=ALL" />
           -->
            <set-backend-service base-url="{{concur-url}}" />
            <set-header name="Authorization" exists-action="override">
                <value>@("Bearer " + context.Variables["token"])</value>
            </set-header>
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-header name="Accept" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-variable name="calledOnce" value="@(true)" />
            <forward-request buffer-request-body="true" />
        </retry>
    </backend>