Add different error message in Azure API Management validate_jwt policy - azure-api-management

I have added the policy to validate jwt token in APIM. right now it validates and send error message and its all working fine. I am trying to send different error message for different scenario for e.g if the toke is not there or invalid I will return 401 with invalida token as error message or if the toekn is expired I want to send 401 with token is expired message. for this I am using something like below, is there any other way we can achieve instead have two different same policy?
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Invalid token or token not found." require-expiration-time="false" require-signed-tokens="true">
<openid-config url="server.config" />
<audiences>
<audience>serveraud</audience>
</audiences>
<issuers>
<issuer>serveriss</issuer>
</issuers>
</validate-jwt>
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Token Expired." require-expiration-time="true" require-signed-tokens="true">
<openid-config url="server.config" />
<audiences>
<audience>serveraud</audience>
</audiences>
<issuers>
<issuer>serveriss</issuer>
</issuers>
</validate-jwt>

You can put a condition check on the "failed-validation-error-message" in the policy. You may leverage "choose" condition :
https://www.codit.eu/blog/azure-api-management-conditional-policies/
APIM Policy to convert and incoming GET request to a POST request for my back end service

Related

Azure APIM Validate-JWT policy not working with Bearer scheme on custom header?

I have declared the following policy:
<validate-jwt header-name="MyCustomHeader" failed-validation-httpcode="401" require-expiration-time="true" require-scheme="Bearer" require-signed-tokens="true">
<openid-config url="https://mytentant over here" />
</validate-jwt>
The problem is that I always get an error if I my request contains the Bearer keyword before the actual token... if I send the token plain and simple, it works!
Also, if instead of using MyCustomHeader I use the "official" Authorization header, the behavior switches back and the Bearer keyword becomes mandatory

Azure API Management - Authentication using HTTP query parameters

I want to expose an API that uses HTTP query parameters for authentication. Something like this:
{root-backendURL}/resource?login=loginName&password=loginPassword
I am using Azure API Management. I've created a new API which points to the backend service, and I've created a new operation called "Resource". For that operation I've added two Query parameters that are required.
Now I want to expose and make use of the APIM Gateway URL that should look something like this:
{root-GatewayURL}/apiName/resource
Adding those two required query parameters will make the URL look like this:
{root-GatewayURL}/apiName/resource?login=loginName&password=loginPassword
When I test the Gateway URL using Postman, I get a 401 response.
{
"code": 401,
"errors": [
{
"message": "Authentication failed."
}
]
}
I've tried to use a Send-Request policy and add from there the query parameters. This way it works.
<rewrite-uri template="/" />
<set-variable name="login" value="loginName" />
<set-variable name="password" value="loginPassword" />
<send-request mode="new" response-variable-name="resource" ignore-error="false">
<set-url>#($"{root-BackendURL}/resource?login={(string)context.Variables["login"]}&password={(string)context.Variables["password"]}")</set-url>
<set-method>GET</set-method>
</send-request>
<return-response>
<set-body>#(new JObject(new JProperty("resource",((IResponse)context.Variables["resource"]).Body.As<JObject>())).ToString())</set-body>
</return-response>
I've double checked the URLs and they are identical. Why do I get different results?
I do not want to use the policy, I want to make it work using the query parameters, because I need to use also an ID for the resource and also other query parameters, for example:
{root}/resource/{id}?limit=25&offset=50&loginName&password=loginPassword

How to perform a 302 Redirect with a forwarding URL

We are using Xamarin and UITest in order to create UI tests for our application.
We are using Azure API management for integration, and am trying to mock our Authentication process.
We are using Xamarin Essentials WebAuthenticator, which opens an external browser in order to do the two step OAuth and load a login page.
Since UITest cannot control anything outside of the app itself, we need to have API management respond by giving a 302 redirect back to the controlling app, with our test authentication tokens that are mocked.
I've tried creating a mock response that returns a 302, with a Location header with the value of our return url for the app. However whenever I test this in the APIM test page, it simply just returns a 200 OK.
Is it possible to make a GET request to APIM, which performs a 302 redirect to a specified uri, with a body of mocked test data?
You may try with a return-response policy.
Something similar to this example:
<when condition="#(context.Request.OriginalUrl.Scheme == Uri.UriSchemeHttp)">
<return-response>
<set-status code="302" reason="Temporary Redirect" />
<set-header name="Location" exists-action="override">
<value>#{
var uri = context.Request.OriginalUrl;
return Uri.UriSchemeHttps + "://" + uri.Host + uri.Path + uri.QueryString;
}</value>
</set-header>
</return-response>
</when>
For your reference: https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#ReturnResponse

How can I throw exceptions in set-body in Azure API Management?

The API that I'm working on now throwing 500 Internal Server Error when the request body do not have certain property inside. I want to eliminate that and instead, it returns another status code such as 400 Bad Request. I get that the error is return from APIM from Azure, how can I throw the error inside the set-body policy since I deserialize the request body in here?
I've read many posts and documents but no luck on succeeding that. Here's my code right now:
<inbound>
<send-request mode="new" response-variable-name="" timeout="60 sec">
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var request = context.Request.Body.As<JObject>(preserveContent: true);
if(String.IsNullOrEmpty((string)request["id"])){
WHAT SHOULD I PUT HERE?
}
return request.ToString();
}</set-body>
</send-request>
</inbound>
Thanks and appreciate if anyone could help.
You can use the return response policy in Azure API Management
https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#ReturnResponse

Consume SOAP API that returns JSON data using ColdFusion

I was given a URL that is supposed to return some JSON data which contains a oAuth Token to access the rest of the API. The API call uses GET and it contains the username and password in the URL.
When I try accessing the API's URL I get the following message:
error unauthorized
error_description An Authentication object was not found in the SecurityContext
Below is an example of my ColdFusion:
<CFHTTP URL="https://test-ows01.website.com/data_api//1.0/oauth/token?grant_type=password&username=HelloWorld&password=MyPassword!" method="GET" result="result">
</CFHTTP>
<cfset content = deserializeJSON(result.filecontent.toString())>
<cfdump var="#content#">
Other info: When I drop the URL (it is not the correct URL for this questions) into a browser I get the “Log In” prompt and after I enter the username: HelloWorld and the password: MyPassword! I am then taken to a page that shows the JSON data which contained the oAuth Token among other data.
I was given a SOAPUI file so review how the API works so if there is some other info I need to provide I may be able to pull it from there.
The server your connecting to is requiring authentication credentials during in the request. Add the username and password to the cfhttp tag to send the credentials within the request.
<cfhttp url="example.com/data_api//1.0/oauth/token?grant_type=password" method="GET" result="result"
username="HelloWorld" password="MyPassword!">
</cfhttp>