Invoking API fails from web page, though succeeds in Test pages - azure

I've create a API populated from a swagger.json file and verified it works in the Test UI. The test UI request succeeds showing the headers passed below.
POST https://apiforqubo.azure-api.net/api/Qubo HTTP/1.1
Host: apiforqubo.azure-api.net
Content-Type: application/json
Ocp-Apim-Subscription-Key: ••••••••••••••••••••••••••••••••
Ocp-Apim-Trace: true
I've added a CORS policy for all operations. This is now updated to reflect the answer below.
The updated policy is:
<policies>
<inbound>
<base />
<cors allow-credentials="true">
<allowed-origins>
<origin>https://apiforqubo.developer.azure-api.net</origin>
</allowed-origins>
<allowed-methods>
<method>POST</method>
<method>GET</method>
<method>PUT</method>
</allowed-methods>
</cors>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
When I try to execute the API from the web page that's generated for the API at: https://apiforqubo.developer.azure-api.net/api-detail, the request fails with the error:
Unable to complete the request
Since the browser initiates the request, it requires Cross-Origin Resource Sharing (CORS) enabled on the server.
What am I missing?
UPDATE: policy statement to reflect specific website as suggested by Vitaliy Kurokhtin in the comments.
Regards,
Rajesh

You've configured it to allow CORS requests only from https://azure-api.net, not from https://apiforqubo.developer.azure-api.net. Either use full URL or wildcard:
<origin>https://*.azure-api.net/</origin>

Please add allowed-headers policy element in your policy in APIM

Related

How to add custom header in Azure API Management before making a call to the backend

I have an Rest Api that is being exposed on Azure. The Azure Api once called calls a WCF Service in the backend.
Firstly I need to transform the JSON Request to XML. Also, To call the SOAP Service I need to add a Custom Header like this:-
<s:Header>
<AuthHeader xmlns="http://abc.security.service">
<UserID>UserID</UserID>
<Token>Token</Token>
</AuthHeader>
</s:Header>
How do I add an "Inbound Policy" that would transform the request to XML and inject the custom header ?
Any ideas or suggestions would be greatly appreciated !!
For this requirement, please refer to the policy in my APIM.
<policies>
<inbound>
<base />
<json-to-xml apply="always" />
<set-body>#{
string inBody = context.Request.Body.As<string>();
string requestBody = inBody.Replace("<Document>","").Replace("</Document>","");
string header = "<s:Header><AuthHeader xmlns=\"http://abc.security.service\"><UserID>UserID</UserID><Token>Token</Token></AuthHeader></s:Header>";
return header + requestBody;
}</set-body>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Please pay attention to the escape character in header, we need to use \" instead of ".

Use Azure API Management for pass-through but returning html showing redirecting

I try to modify the backend of our api management from resource to a webapp api.
I have taken Use Azure Api Management as a passthrough as a reference.
the exposed api is:
https://service-api-management.azure-api.net/api-name/operation-name
the actual api I want to call is:
https://service-name.azurewebsites.net/api/Skills/Async/operation-name
apart from the uri, the request body and header should remain the same. So I have the below policy set up to change the uri. But the response is a html showing redirect.
Curiously about why it returns a html showing redirecting and how can I make the redirect work properly. Any input would be appreciated.
Policy:
<policies>
<inbound>
<base />
<set-backend-service base-url="https://service-name.azurewebsites.net" />
<rewrite-uri template="#(context.Request.Url.Path.Replace("/operation-name","/api/Skills/Async/operation-name"))" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Response:
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<title>Redirecting</title>
......
Test and see what your backend service returns to a tool like Postman or Fiddler, those would be best to emulate regular HTTP request not sent by browser. Perhaps backend expects some header in request that is sent implicitly, or maybe redirect is just very fast and not noticeable by user. To make it work through APIM you'll hve to take care to either not trigger redirect or make it redirect to APIM again. To some extent redirect-content-urls policy may be of use here: https://learn.microsoft.com/en-us/azure/api-management/api-management-transformation-policies#MaskURLSContent

Azure APIM Policy - When to use <backend> </backend>

https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-policies
<policies>
<inbound>
<!-- statements to be applied to the request go here -->
</inbound>
<backend>
<!-- statements to be applied before the request is forwarded to
the backend service go here -->
</backend>
<outbound>
<!-- statements to be applied to the response go here -->
</outbound>
<on-error>
<!-- statements to be applied if there is an error condition go here -->
</on-error>
</policies>
When do we use backend sections in the policy?
Looks like setting the backend url using is also done on <inbound> node only.
Thanks for your time.
that part is used to do any transforms\checks on the request before forwarding it to the backend, for example I was adding headers to the request and validating oauth tokens.

Is it possible to use the subscription-key query string parameter with Azure API Management SOAP-passthrough?

We use API Management to expose several API's. One of the API's we expose is configured as a SOAP-passthrough API but we are facing some issues with it regarding authentication of APIM.
When we use the Ocp-Apim-Subscription-Key header for passing the query string it all works correct and the API is returning it's content correct.
When we use the subscription-key query string parameter the API is returning a 401 Unauthorized. I tested this behavior in Postman and changing the way of sending the subscription key is resulting in this behavior.
An implementation detail of this API is that it exposes an existing WSDL and routes this SOAPAction to an Azure Function via the policy. In the Application Insights of the function I can verify that the function is never invoked when I get a 401 but it is invoked when I get a successful call (using the header).
Is this normal behavior? Am I doing things wrong? Or is it a bug in APIM?
This might be an issue with the way we do routing for SOAP Passthrough. You will notice in the API setup that we add on a query parameter to identify the SoapAction that an operation will be matched to. It may be that your the api key query parameter is getting overwritten when adding the SoapAction parameter to the inbound request. I will investigate and let your know.
We currently use a workaround around this problem with the following policy. Instead of changing the backend-server url in the policy we send a request and set the response of that request as a response for this api. Below you can find our policy which is working with the subscription-key in the query string.
<policies>
<inbound>
<base />
<send-request mode="copy" response-variable-name="response" timeout="20" ignore-error="false">
<set-url>{{BackendServer_URL}}</set-url>
</send-request>
<!--return-response response-variable-name="reponse" /-->
<choose>
<!-- If StatusCode is not OK, return Unauthorized with the reason. -->
<when condition="#(((IResponse)context.Variables["response"]).StatusCode != 200)">
<return-response response-variable-name="reponse">
<set-status code="401" reason="Unauthorized" />
<set-body>#(((IResponse)context.Variables["response"]).Body.As<string>())</set-body>
</return-response>
</when>
<otherwise>
<return-response response-variable-name="reponse">
<set-status code="200" />
<set-header name="Content-Type" exists-action="override">
<value>text/xml; charset=utf-8</value>
</set-header>
<set-body>#(((IResponse)context.Variables["response"]).Body.As<string>())</set-body>
</return-response>
</otherwise>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>

Azure APIM as pure proxy

I am trying to deal with an Backend API(REST) with no swagger documents to be accessed through Azure APIM.
I want all the calls directed to the Backend API with me not manually creating GET/PUT/POST for all the resources. My inbound policies for all operations is below
'
<policies>
<inbound>
<set-variable name="requestPath" value="#(context.Request.Url.Path)" />
<base/>
<set-backend-service base-url="https://*****/****/" />
<rewrite-uri template="#(context.Request.Url.Path)" copy-unmatched-params="true" />
</inbound>
<backend>
<base/>
</backend>
<outbound>
<base/>
</outbound>
</policies>
`
However when hit the APIM i was given
{
"statusCode": 404,
"message": "Resource not found"
}
Any help is appreciated Thanks
The easy way to do this is to create one operation for each HTTP method you support and use /* for the template. This will match any inbound path/query and forward it to the backend.

Resources