Cristian E.
Cristian E.

Reputation: 3583

Azure Api Management - cors policy. Cannot provide <allowed-origins> from named values dynamically

Objective:

Dynamically pass cors origins to the cors policy from named values.

Example:

Suppose I have the following named values:

name: cors-origins
value: https://domain1.com;https://domain2.com

and the CORS policy which intends to make use of this named value cors-origins:

<policies>
<inbound>
    <cors>
        <allowed-origins>
            // Here I need to use {{ cors-origins }}
            // The expected output is:
            // <origin>https://domain1.com</origin>
            // <origin>https://domain2.com</origin>
        </allowed-origins>
        <allowed-methods>
            <method>GET</method>
            <method>POST</method>
        </allowed-methods>
    </cors>
</inbound>
<backend>
    <forward-request />
</backend>
<outbound />
<on-error />
</policies>

What I tried so far:

  1. Dynamically creating the <allowed-origins> section:

Snippet:

...
<cors>
     @{
        var origins = "{{cors-origins}}".Split(';');
        return new XElement("allowed-origins", origins.Select(domain => new XElement("origin",domain)));
        // outputs:
        // <allowed-origins>
        //   <origin>https://domain1.com</origin>
        //   <origin>https://domain2.com</origin>
        // </allowed-origins>
     }
   
...
</cors>

Errors with: The element 'cors' cannot contain text. List of possible elements expected: 'allowed-origins, allowed-headers, expose-headers, allowed-methods'

  1. Dynamically creating only the <origin> elements.

Question: Is there a way to achieve the intended goal?

Upvotes: 1

Views: 1063

Answers (1)

Ahmed El Kilani
Ahmed El Kilani

Reputation: 345

Not possible to dynamically add tags in APIM policies. What you can do is to read the request origin from the request header and check if it exists in one of the list of allowed origins.

Reference: How to make Azure API Management (API Gateway) CORS policy dynamic?

For your case it should be something like:

<fragment>
<cors allow-credentials="true">
    <allowed-origins>
        <origin>@{
            var origins = "{{cors-origins}}".Split(';');
            string origin = context.Request.Headers.GetValueOrDefault("Origin", "");
            bool isAllowedOrigin = Array.IndexOf(origins, origin) > -1;
            return isAllowedOrigin ? origin : "";
        }</origin>
    </allowed-origins>
    <allowed-methods preflight-result-max-age="300">
        <method>*</method>
    </allowed-methods>
    <allowed-headers>
        <header>*</header>
    </allowed-headers>
    <expose-headers>
        <header>*</header>
    </expose-headers>
</cors>

Upvotes: 0

Related Questions