Janne Mattila

From programmer to programmer -- Programming just for the fun of it

Standard Logic App and authentication with EasyAuth

Posted on: November 18, 2024

I’ve previously blogged about EasyAuth e.g., App Service and OpenID Connect with Salesforce and Application Gateway and App Service authentication.

In this post, I’ll show how to use authentication with EasyAuth in a Standard Logic App. This post heavily builds on top of the post: Trigger workflows in Standard logic apps with Easy Auth.

Scenario:

We’ll create 3 app registrations, so that we can test authentication with Logic App:

First, we’ll create the app registration used by the Logic App authentication:

# Workflow application:
$integrationApp = New-AzADApplication `
  -DisplayName "Integration Workflow" `
  -SignInAudience AzureADMyOrg
Update-AzADApplication -InputObject $integrationApp `
  -IdentifierUri "api://$($integrationApp.AppId)"
New-AzADServicePrincipal -ApplicationId $integrationApp.AppId

Similarly, we’ll create 3 client applications and their secrets:

# Integration client application 1:
$integrationClientApp1 = New-AzADApplication `
  -DisplayName "Integration Client 1" `
  -SignInAudience AzureADMyOrg
New-AzADServicePrincipal -ApplicationId $integrationClientApp1.AppId
$integrationClientApp1Secret = New-AzADAppCredential `
  -ObjectId $integrationClientApp1.Id `
  -EndDate (Get-Date).AddYears(1)

Repeat the above for the other client applications:

Next, we’ll prepare for the infrastructure-as-Code deployment. We have to pass clientId and integrationClientIds as parameters, so that the Logic App can be configured with the correct authentication settings. IntegrationClientIds is an array of client application IDs that are allowed to call the Logic App. No other client applications are allowed to call the Logic App. Here’s the deployment:

# Prepare parameters for the deployment:
$clientId = $integrationApp.AppId
$integrationClientIds = $integrationClientApp1.AppId, $integrationClientApp2.AppId

# Deploy the Standard Logic App with authentication enabled:
$deployment = .\deploy.ps1 -ClientId $clientId -IntegrationClientIds $integrationClientIds
$deployment.outputs.uri.value

Few key points from the deployment script:

After the deployment, we can see the following resources in the resource group:

Now, we can implement simple HTTP trigger-based workflow using Azure Portal and leverage ready-made templates:

I’ll add simple payload to the response:


Now, we are ready to test our Logic App. I’ll first test with the Integration Client 1 application. Let’s get the token for the application:

# Integration Client 1 test:
$tenantId = (Get-AzContext).Tenant.Id
$clientPassword = ConvertTo-SecureString $integrationClientApp1Secret.SecretText -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential($integrationClientApp1.AppId, $clientPassword)
Connect-AzAccount -ServicePrincipal -Credential $credentials -TenantId $tenantId

$integrationClient1Token = Get-AzAccessToken -Resource $integrationApp.AppId -AsSecureString
$integrationClient1Token.Token | ConvertFrom-SecureString -AsPlainText | Set-Clipboard

Let’s quickly study the token in jwt.ms:

We can see that:

Now, we can test invoking the Logic App with the token:

Invoke-RestMethod `
  -Uri $requestUri `
  -Authentication Bearer `
  -Token $integrationClient1Token.Token

The response is:

Hello Client App!

We can repeat the same steps for the Integration Client 2 application and see the same response. Everything works as expected.

Let’s test with the Integration Client 3 - Not enabled application. Token seems to be similar as before and AppId matches our configured app:

However, when we try to call the Logic App with the Integration Client 3 - Not enabled application, we get:

Invoke-RestMethod: You do not have permission to view this directory or page.

This is of course expected, since this application is not in the allowed client application list.

Let’s quickly see the configured setting of our Logic App:

Here’s a difference when comparing to typical App Service EasyAuth configurations:

So, we still need to allow unauthenticated access, since it is used by other operations e.g., by the Logic App designer.

More information about configuration options can be found from the official documentation:

Configure your App Service or Azure Functions app to use Microsoft Entra sign-in

Enable OAuth 2.0 with Microsoft Entra ID

What is the difference between allowedApplications and identities in the configuration?

I’ll leave the delegated permissions scenario for another blog post.

You can further down narrow the access by defining more granular application roles: Daemon client application (service-to-service calls) Here is my App Service authentication and service-to-service integration example about it.

Conclusion

The above steps showed how to secure a Standard Logic App with EasyAuth authentication. Please remember, that this was only about the identity part. There are other aspects to consider when securing your Logic App including network restrictions etc.

This scenario was about the incoming requests to Logic App. If you need to call other services from the Logic App, you need to consider the outgoing requests as well. Typically, you would use Managed Identity for that.

You can find the full source code from my GitHub repository. Just open setup.ps1 and run commands line by line and you have the same setup as I had in this blog post:

I hope you find this useful!