Azure Logic Apps: securing HTTP Triggers with Microsoft Entra ID authentication

Lots of time ago I wrote a post about securing the HTTP triggered workflows created with Power Automate. You can read this post here.

When you create a workflow with Power Automate or Azure Logic Apps and you use the “When an HTTP request is received” trigger, a public url to invoke the workflow via an HTTP request is automatically generated when saving the flow.

The url has the following format:

https://<workflow-endpoint-base-uri>sp=<permissions>sv=<SAS-version>sig=<signature>

In the workflow url is embedded the shared access signature (SAS) version and the signature itself. This signature is passed through as a query parameter and must be validated before the workflow can be executed. This signature is generated using a unique combination of a secret key per workflow, the trigger name, and the operation that is performed.

Having a public url like this could be ok if you’re absolutely sure that only who need to call the workflow knows the signature, but if the url is leaked then anyone who have its value could potentially trigger your workflow and execute the defined actions.

Today I had a talk with the IT department of a customer for a new cloud project where Azure Logic Apps http-triggered workflows need to be secured in a more robust way exactly for this scope.

If you need a strongest way of securing your http-triggered flows, you can:

  • use Azure AD (or Microsoft Entra ID) authentication OR
  • embed the flow into Azure API Management.

In this mentioned scenario, we discarded the Azure API Management solution simply because the customer has not too much flows requiring this type of security and so costs of this service could be too high. For this reason we decided to go for the Azure AD (ops, Microsoft Entra ID) authentication.

I was absolutely sure to have written in the past a post about how to setup Azure AD authentication with Azure Logic Apps, but this was not true. So here is a post explaining how to do that (dear customer, I know that you’re reading here and this post is for you…).

How to secure your Azure Logic Apps HTTP trigger with AAD (Microsoft Entra ID)?

For explaining how to do that, I have created a simple HTTP-triggered workflow like the following:

Here I have a flow receiving an HTTP request with a JSON body. I read a value from the request body and I assign this value to a variable.

When you save the workflow, the public url is created and it’s in the format like:

https://prod-174.westeurope.logic.azure.com:443/workflows/WORFLOWID/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE

To use AAD authentication in our flow we need to set the trigger condition in order to check that the incoming POST call triggering the flow has always an Authorization header with a Bearer token.

To do that, select the When a HTTP request is received trigger’s Settings:

and add the following trigger condition:

 @startsWith(triggerOutputs()?['headers']?['Authorization'], 'Bearer')

Then we need to register an application into Azure AD (Microsoft Entra ID application). The steps are quite familiar to many of you I think and they are documented here. You also need to create a secret for this app registration (don’t forget to take note of it).

We can test the acquisition of a token by sending a POST request to the following url:

https://login.microsoftonline.com/TENANTID/oauth2/token

and by passing the following parameters in the request body:

  • client_id: client (application) ID of your application registration in AAD.
  • client_secret: the secret of your application registration.
  • grant_type: client_credentials
  • resource: https://management.core.windows.net

If parameters are correctly inserted, you should have a valid token in response:

To trigger the Azure Logic App workflow, we need to send a POST request to the workflow url without the signature parameters, so just the following url (remove the sp,sv and sig parameters):

https://prod-174.westeurope.logic.azure.com:443/workflows/WORFLOWID/triggers/manual/paths/invoke?api-version=2016-10-01

and passing the Auhtorization parameter in the request header (with content = Bearer + the previously obtained token).

Here is the response:

We have a 401 – Unauthorized response saying that an OAuth policy is not enabled for the workflow.

To enable OAuth for the workflow, we need to open the Logic Apps designer and select the Code view:

Here go into the trigger definition and add the following parameter:

"operationOptions": "IncludeAuthorizationHeadersInOutputs"

Then, select the Authorization menu on the left pane and here add a new policy:

Give a name for the new AAD policy and insert the following parameters:

Save the policy.

In this way we have configured our Logic App to accept requests only from a specific Azure app registration.

Now we can acquire a new token in AAD and call the Azure Logic Apps workflow again by sending a POST request to the flow url (without signature as previously explained) and by passing the Authorization parameter in the request header.

Now the request is accepted:

We now have a 202 – Accepted HTTP status in the response and if you inspect the workflow you will see that it will be successfully triggered:

Now only AAD authenticated clients can call our HTTP-triggered workflow and our integration is more secure.

3 Comments

  1. Hi, with the token obtained with V2.0 (/oauth2/v2.0/token) we get a claims error:
    “One or more claims either missing or does not match with the open authentication access control policy.”
    with version 1, no problem …

    Very good article, thanks.

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.