Delay after setting the response in ApiManagement - azure-api-management

We use the Api Management to mock endpoints. We set mock endpoints during tests and depending on which test is running, we change the mock.
With help of PolicyContract we set our mocked content:
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" />
<set-header name="Content-Type" exists-action="override">
<value>text/xml</value>
</set-header>
<set-body template="liquid">
<mockedcontent>content</mockedcontent>
</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
In code we use the nuget package Microsoft.Azure.Management.ApiManagement to set the PolicyContract. When we call the IApiOperationPolicyOperations.CreateOrUpdateWithHttpMessagesAsync the operation is succesful and afterwards IApiOperationPolicyOperations.GetWithHttpMessagesAsync returns new updated PolicyContract. But here comes the problem. The mocked endpoint itself doesn't return the set mocked content directly. There is a delay before the endpoint is being updated. Currently we have code to check if the endpoint is updated. But this is creating other problems in our architecture.
Is there another way how to detect if the mock endpoint has really updated?

Related

Create Custom policy in Azure API Management

I want to validate custom claims which are part of JWT token. Token has custom user claims, application claims and other details.
For user claims, I want to have custom policy/block like
<validate-logintype> {validation logic in this block} </validation-logintype>
For application claims, custom policy like
<request-from> {validation logic} </request-from>
Include the above blocks in actual API policy
User API:
<policy>
<inbound>
<validate-logintype>
<base />
</inbound>
</policy>
Can someone please help how this can be implemented.
something like this?
<policies>
<inbound>
<base />
<set-header id="apim-generated-policy" name="Ocp-Apim-Subscription-Key" exists-action="delete" />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
<openid-config url="https://login.microsoftonline.com/<yourtenant>/.well-known/openid-configuration" />
<audiences>
<audience>{{claim1}}</audience>
</audiences>
</validate-jwt>
</inbound>

API Management - the same policy created for every operation

When I add an API using the Function App option. All the functions are imported as operations and every operation has the same backend policy:
<inbound>
<base />
<set-backend-service id="apim-generated-policy" backend-id="myfunctionapp" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
I have a lot of these operations and all of them have the same policy. There is a way to create a shared policy for all operations. So it would seem better to create one shared policy instead of policy for each operation.
Is there a way, during the "add API" step, to specify a shared policy for all operations and not have these policies on each operation? I couldn't find a way (at least not in Azure UI). Is there another way to do that?
If you want to apply the policy to all operations, select All operations.
Select the </> (code editor) icon in the Inbound processing section.
And then paste the desired policy code into one of the appropriate blocks.
<policies>
<inbound>
<base />
<set-backend-service id="apim-generated-policy" backend-id="myfunctionapp" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
For more details you could refer to this article.

Azure API Management Restrict multiple caller IP Address API in API endpoint level

I wanted to restrict some IP's in Azure APIM policy level.
I went thro below links;
https://learn.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#RestrictCallerIPs
Azure API Management Restrict multiple caller IP Address
But not sure how can I do this to API end-point level using policy scope
I have below code in the policy.xml:
<policies>
<inbound>
<base />
<!-- statements to be applied to the request go here -->
<authentication-certificate thumbprint="#((string)context.Variables["ClientCertificateThumbprint"])" />
<rate-limit-by-key calls="100" renewal-period="60" counter-key="#(context.Request.Headers.GetValueOrDefault("Ocp-Apim-Subscription-Key"))" />
<cors>
<allowed-origins>
<origin>*</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="600">
<method>*</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
<expose-headers>
<header>*</header>
</expose-headers>
</cors>
<ip-filter action="allow">
<address>55.11.187.20</address>
<address-range from="186.168.95.0" to="186.168.95.20" />
</ip-filter>
</inbound>
<backend>
<base />
<!-- statements to be applied before the request is forwarded to
the backend service go here -->
</backend>
<outbound>
<base />
<!-- statements to be applied to the response go here -->
</outbound>
<on-error>
<base />
<!-- statements to be applied if there is an error condition go here -->
</on-error>
</policies
>
Using control flow in Advanced policies you can change the scope to API endpoint level (operation) to restrict IP addresses as below
<choose>
<when condition="#(context.Operation.Id.Equals("StatusGet"))">
<ip-filter action="allow">
<address>55.11.187.20</address>
<address-range from="186.168.95.0" to="186.168.95.20" />
</ip-filter>
</when>
</choose>
</inbound>
Refer: https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies
Navigate to Azure portal, your APIM service, APIs.
Click API you want to apply IP filter to
In the "Inbound processing" section click "Add policy" and select IP filter.

Is Limit call rate by subscription supported in Consumption tier?

I am trying to add a rate-limit policy for an API management (per API Management access restriction policies) and I am not sure if I do something wrong or if documentation is not correct.
According to the documentation, the
Set usage quota by key
Limit call rate by key
are not available in consumption tier, but Limit call rate by subscription has no such notice, so it should work (plus Set usage quota by subscription can be set).
I have an Azure API Management, I have created a sample API and a product and in the policy of the product is:
<policies>
<inbound>
<base />
<quota calls="100" renewal-period="86400" />
<rate-limit calls="20" renewal-period="90" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
When I click on Save, I get
One or more fields contain incorrect values:
Error in element 'rate-limit' on line 16, column 10: Policy is not allowed in this sku 'Consumption'
Is there a way to set the rate-limit (=am I missing something) for consumption tier or is the documentation not correct?
You can now use the rate-limit and quota tag in policies at API level.
<policies>
<inbound>
<base />
<rate-limit calls="5" renewal-period="60" remaining-calls-variable-name="remainingCallsPerSubscription" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Using quotas:
<policies>
<inbound>
<base />
<quota calls="10000" renewal-period="3600" />
</inbound>
<outbound>
<base />
</outbound>
</policies>
Edit: on the consumption tier you can only apply these policies on API level. (So they apply to everyone that uses the API)
There is an ongoing update, once complete (a few days at most) "rate-limit" will be enabled for Consumption SKU, "rate-limit-by-key" disabled.

Azure API Management: Doing a global policy for set-backend-service results in scope error

So globally on my API service, I always wish to set the backend service URL based on certain calling regions.
According to this MSDN library article, using the set-backend-service policy sounds perfect for this, and it's a global policy according to its policy scope at the bottom.
However, even posting their exact example...
<policies>
<inbound>
<choose>
<when condition="#(context.Request.Url.Query.GetValueOrDefault("version") == "2013-05")">
<set-backend-service base-url="http://contoso.com/api/8.2/" />
</when>
<when condition="#(context.Request.Url.Query.GetValueOrDefault("version") == "2014-03")">
<set-backend-service base-url="http://contoso.com/api/9.1/" />
</when>
</choose>
</inbound>
....results in an error:
"Error in element 'set-backend-service' on line 0, column 0: Policy is
not allowed in the specified scope"
I can't figure out how to make it any simpler of a situation to troubleshoot. I even removed the conditional statement and just left the policy alone and it still shows the scope error.
I know this global scope works okay, since I was able to put in an xml-to-json policy as a temporary test and save successfully.
I would figure someone ran into this issue already, as this must be a common use case for this policy. Otherwise, I think the MSDN article is out of date, unless anyone here can see any issues.
Here's my policy scope for global:
Change the quotes to single quotes where "version" is. I just ran the following no problem:
<policies>
<inbound>
<choose>
<when condition="#(context.Request.Url.Query.GetValueOrDefault('version') == '2013-05')">
<set-backend-service base-url="http://contoso.com/api/8.2/" />
</when>
<when condition="#(context.Request.Url.Query.GetValueOrDefault('version') == '2014-03')">
<set-backend-service base-url="http://contoso.com/api/9.1/" />
</when>
</choose>
<base />
</inbound>
<outbound>
<base />
</outbound>
</policies>