实现 X-CSRF 模式Implement X-CSRF pattern

本文介绍 Azure API 管理策略示例,该示例演示如何实现许多 API 使用的 X-CSRF 模式。This article shows an Azure API management policy sample that demonstrates how to implement X-CSRF pattern used by many APIs. 此示例特定于 SAP 网关。This example is specific to SAP Gateway. 若要设置或编辑策略代码,请执行设置或编辑策略中所述的步骤。To set or edit a policy code, follow the steps described in Set or edit a policy. 若要查看其他示例,请参阅策略示例To see other examples, see policy samples.

策略Policy

将代码粘贴到“入站”块中。Paste the code into the inbound block.

<!-- The policy defined in this file shows how to implement X-CSRF pattern used by many APIs. The example is specific to SAP Gateway.  -->

<!--    Detailed description of the scenario and solution can be found on: -->
<!--      http://blog.ibiz-solutions.se/uncategorized/exposing-sap-gateway-services-with-api-management/. -->

<!-- Copy the following snippet into the inbound section. -->

<policies>
  <inbound>
    <base/>
    <!-- Set the URL to the service. -->
    <rewrite-uri template="sap/opu/odata/sap/ZCAV_AZURE_CS_ORDER_SRV/ItHeaderSet('{oid}')" />

    <!-- Creating a subrequest "fetchtokenresponse" and set it as GET request to get the token and cookie.-->
    <send-request mode="new" response-variable-name="fetchtokenresponse" timeout="10" ignore-error="false">
      <set-url>@(context.Request.Url.ToString())</set-url>
      <set-method>GET</set-method>
      <set-header name="X-CSRF-Token" exists-action="override">
        <value>Fetch</value>
      </set-header>
      <set-header name="Authorization" exists-action="override">
        <value>{{http-basic-auth-header-value}}</value>
      </set-header>
      <set-body>
      </set-body>
    </send-request>

    <!-- Extract the token from the "fetchtokenresponse" and set as header in the POST request. -->
    <set-header name="X-CSRF-Token" exists-action="skip">
      <value>@(((IResponse)context.Variables["fetchtokenresponse"]).Headers.GetValueOrDefault("x-csrf-token"))</value>
    </set-header>

    <!-- Extract the Cookie from the "fetchtokenresponse" and set as header in the POST request. -->
    <set-header name="Cookie" exists-action="skip">
      <value>
        @{
        string rawcookie = ((IResponse)context.Variables["fetchtokenresponse"]).Headers.GetValueOrDefault("Set-Cookie");
        string[] cookies = rawcookie.Split(';');
        string xsrftoken = cookies.FirstOrDefault( ss => ss.Contains("sap-XSRF"));
        return xsrftoken.Split(',')[1];}
      </value>
    </set-header>
  </inbound>
  <backend>
    <base/>
  </backend>
  <outbound>
    <base/>
  </outbound>
  <on-error>
    <base/>
  </on-error>
</policies>

后续步骤Next steps

了解有关 APIM 策略的详细信息:Learn more about APIM policies: