An alternative way of getting OAuth working in Anypoint Studio
Getting software to work with OAuth is usually one of the easiest things a developer could be tasked with, if s/hehas done it a few times: Create an HTTP client method that sends four values to an OAuth provider, then pass the response to the next HTTP client method as a variable to be used in the Authorization header.
Doing that in Anypoint Studio, for a Mulesoft application, was an uphill struggle of resolving one error message after another. For those who aren’t too familiar with Mulesoft, it’s essentially a load of XML files that get interpreted by a large collection of compiled Java programs to create a Mulesoft application. The XML files are generated from a ’low-code’ abstraction in Anypoint Studio. Most problems I run into are related to configurations and dependencies - they are numerous. Documentation is relatively lacking, and there’s hardly anything on Stack Overflow.
The conventional documented method of using OAuth in Anypoint Studio is to have the main HTTP Request component handle it natively, but the problem is the OAuth request and response won’t show in the MUnit trace, and that means there’s no way of knowing whether the HTTP Request was getting a 403 or 500 response after it’s been authenticated.
To debug this, a separate HTTP Request component is needed to handle the OAuth. I don’t know whether it’s worth giving this component its own flow and unit test. The next problem is the OAuth response won’t get passed to the main HTTP Request, since the flow has only one payload variable, and that always refers to the source input. The OAuth response must instead be assigned to a target variable in the Advanced Settings. As I soon discovered, this can actually be done without adding a variable component.
The next bit was frustrating. Looking at the Body tab for the HTTP Request, it’s logical to assume it’s for the HTTP payload, and it’s the last place we’d expect to set the Client ID and Client Secret, if the OAuth server expects them as x-www-form-urlencoded parameters. We wouldn’t expect it to resemble a JSON payload. Of course, I spent a hour trying to figure out why the expressions didn’t work in the Headers and Query Parameters tabs. But, it turned out they do need to be defined as a DataWeave expression in the Body tab.
%dw 2.0
output application/x-www-form-urlencoded
---
{
grant_type: "client_credentials",
client_id: p('secure::oauth-api.clientId'),
client_secret: p('secure::oauth-api.clientSecret'),
scope: "application"
}
I’ve avoided hard-coding the sensitive values and instead used DataWeave syntax for reading the Client ID and Client Secret from the config.secure file.
With that in place, and the MUnit trace showing an OAuth token was being returned, the main HTTP Request needs a DataWeave expression, that references the target variable, to set the Authorization header field:
output application/java
---
{
Authorization : "Bearer " ++ (vars.oauthToken.access_token as String),
"Content-Type" : "application/json"
}
It’s best to define any other header field parameters here also, as switching to the table view might wipe the DataWeave code. Why is ‘Content-Type’ in quotes, and ‘Authorization’ not in quotes, though?
Running MUnit, the OAuth token should appear in the debug trace, if we set a breakpoint on that HTTP Request, and that will help rule out the OAuth response as the cause of errors.