3

We have the current situation:

  • In Azure API manager we build some APIs based on a Swagger definition.
  • The provider of the APIs provided us with a client id and secret.
  • Some of these API calls need to be authenticated with a bearer token which is generated on the provider's API infrastructure with a /token endpoint mentioned above and we want to integrate the authentication flow for these API calls in APIM (since the frontend will be authenticated in another way (CORS probably))
  • We tried various approaches using all kinds of variations in "OAuth2.0" service configurations in the APIM setting and apply them to the API definitions by We kept getting Unauthorized 401.

As starting point we used https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad, but most of the the explanations we found concerned using AD, which we don't need as far as we understand.

We tried to implement the following OAuth 2.0 Postman Authorization configuration into APIM (which actually works in Postman).

[1]: https://i.sstatic.net/e3zSh.png

Is there a simple and straight forward way to tell APIM to do a call to the token URL with a given ClientId and secret and add the authorization header with a bearer token to the backend API?

2 Answers 2

3

Thanks to Gary for pointing me in the right direction. I'm quiet new to the topic, so my approach might be far from perfect but it works.

I ended up in modifying the inbound policies of the API call and added the following (replace xxxx's with the appropriate settings)

<policies> <inbound> //.... <send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true"> <set-url>https://xxxxxxxxxx.azurewebsites.net/connect/token</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-header name="Accept" exists-action="override"> <value>*.*</value> </set-header> <set-body> @("grant_type=client_credentials&scope=xxxxxx&client_id=xxxxxxxx&client_secret=xx") </set-body> </send-request> <set-variable name="bearerToken" value="@(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["access_token"].ToString())" /> <set-header name="Authorization" exists-action="override"> <value>@("Bearer " + (string)context.Variables["bearerToken"])</value> </set-header> <set-header name="Content-Type" exists-action="override"> <value>application/json</value> </set-header> <set-header name="Accept" exists-action="override"> <value>*/*</value> </set-header> </inbound>

Short explanantion

  1. A new request is initaited which response will be stored in the variable (token state)
  • The method is defined as POST
  • Headers for the request are set (Centent-Type & Accept)
  • The body of the request is defined
  1. Since the response of the token request (stored in tokenstate) is JSON formatted, the response of the request is cast to a JObject and the "access_token" is stored in the "bearerToken" variable (alternatively you could do without assigning the variable and put this line immediately in the next step.

  2. Set the "Autorization" header with the value "Bearer " + [bearerToken]

the additional steps (Set header Content-Type & Accept) I needed to be able to debug, but in normal cases they will be added by the requesting client of the API.

Sign up to request clarification or add additional context in comments.

1 Comment

I was able to set it up with this code, except that the accept-header *.* failed in the backend. Instead */* should be used.
1

Yes - you can do this and here is a Curity resource that follows a similar process:

  • Make an OAuth request to get a JWT based on an incoming credential
  • Forward it to the downstream API
  • Cache the result for subsequent requests with the same incoming credential

Your case is a little different but uses the same building blocks. You just need to adapt the OAuth message to use the Client Credentials flow.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.