3

I have a backend API I want to proxy by using Azure API Management. This backend API requires me to provide a Bearer Oauth2 token. I want to use Azure APIM to handle the Oauth2 flows for me, and I want to expose a very simple API that will be consumed by client apps. I want to avoid my client App to use Oauth2. How can I handle it with APIM? I found a lot of samples demonstrating how to protect a backend API with Oauth2, but it is not the use case I'm trying to implement. Thanks.

David GROSPELIER
  • 772
  • 1
  • 9
  • 35

2 Answers2

3

Here is a policy snippet to make this work:

    <send-request ignore-error="true" timeout="20" response-variable-name="bearerToken" mode="new">
        <set-url>{{authorizationServer}}</set-url>
        <set-method>POST</set-method>
        <set-header name="Content-Type" exists-action="override">
            <value>application/x-www-form-urlencoded</value>
        </set-header>
        <set-body>   
            @{
                return "client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_credentials";
            }
        </set-body>
    </send-request>

    <set-header name="Authorization" exists-action="override">
        <value>
            @("Bearer " + (String)((IResponse)context.Variables["bearerToken"]).Body.As<JObject>()["access_token"])
        </value>
    </set-header>

    <!--  We do not want to expose our APIM subscription key to the backend API  -->
        <set-header exists-action="delete" name="Ocp-Apim-Subscription-Key"/>

From: https://github.com/orangetoken/api-management-policy-snippets/blob/master/Snippets/Add%20Azure%20AD%20OAuth2%20bearer%20token%20to%20request%20to%20AD%20protected%20API.xml

And on the APIM policy snippets branch from the APIM team https://github.com/Azure/api-management-policy-snippets/blob/master/examples/Get%20OAuth2%20access%20token%20from%20AAD%20and%20forward%20it%20to%20the%20backend.policy.xml

Erik Oppedijk
  • 3,496
  • 4
  • 31
  • 42
  • 1
    Its actually there now: https://github.com/Azure/api-management-policy-snippets/blob/master/examples/Get%20OAuth2%20access%20token%20from%20AAD%20and%20forward%20it%20to%20the%20backend.policy.xml – Dibran Nov 15 '18 at 12:27
  • I keep getting internal server error using this policy, "message": "Expression evaluation failed.", "expression": "\"Bearer \" + (String)((IResponse)context.Variables[\"bearerToken\"]).Body.As()[\"access_token\"]", "details": "Unexpected character encountered while parsing value: <. Path '', line 0, Please advise – Sai Feb 18 '19 at 23:06
  • How is this an acceptable solution. This is making a additional API call for every request. However, the purpose of the Access Token is that they have expiration and till it is expired, one should not be using a new token. This would not work for a production load setup. Needs caching of the token's, validation of the token expiration and other things. Have Azure team yet not found a proper solution to this? Sorry my frustration is towards Azure, this is very helpful. – Varesh Aug 07 '23 at 15:49
0

What you need to do is add a header to request - use set-header policy to Set Authorization header to a desired value. That would work well if you can hardcode token in policy.

If you cant - the you have to organize OAuth flow inside policy using send-request. In short, what you'll be doing is sending you app id and secret to OAuth endpoint and parsing its response to obtain token and attach it to request.

Vitaliy Kurokhtin
  • 7,205
  • 1
  • 19
  • 18