3 minute read

Recently, we have been working on an integration of a customer’s on-premises system with Power Apps. The on-premises system is not accessible from the Internet and exposes the data on few REST-based endpoints. We needed to synchronize the data on daily basis and reflect the changes in Power Apps. In order to access the on-premises REST API, we decided to go with On-premises data gateway which plays nicely with both Power Platform and Microsoft Azure.

The customer’s API is protected by their custom OAuth2 authorization server (client_credentials flow is supported). Initially I thought - we did numerous integrations like this, both with REST APIs and various databases to which we connect via the gateway, so it’s going to be quite simple. Yeah, well.. Turns out, we never did a combination of HTTP requests via the gateway.

So I started with trying out the HTTP action but after doing some research, it turns out it isn’t supported in scenarios with the gateway. So my next thought was - we are building lots of custom connectors which actually support the gateway. I went ahead and created a custom connector and manually built a Swagger definition around the REST endpoints. The issue came after I tried to setup authentication. Turns out, that when you use the gateway, you are stuck with Windows and Basic authentication only.

Alrighty, we are engineers, let’s come up with something creative - let’s just define the Authorization header and give in a value with each request (that is the best way anyways, since client_credentials flow isn’t supported by custom connectors as of now - only some first party connectors can use it). Well, turns out you can’t do that:

This is where it gets confusing - the connector editor tells you that you can’t use Authorization header and to use API key authentication type instead which is not supported with the gateway…

So while getting quite desperate with this entire situation, I started thinking about alternatives - like using Azure Relay to expose the endpoints - but I wanted to avoid this, because it would introduce another complexity with customer’s security department (this one is kinda large corp) and we already had the gateway setup and approved.

Then, I started looking at all the connectors supported by Flow. For a fact, I knew that the File System connector supports the gateway and has a setting called gatewayParameters. Quick use of Google Search allowed me to get all the connectors which support the gateway (File System, BizTalk Server, MSSQL, MySQL, HTTP with Azure AD, SAP, …).

Wait.. HTTP with Azure AD? That’s like making a HTTP call right? Of course! So I went ahead and set up the HTTP with Azure AD connector’s connection with the base URL of customer’s on-premise REST API. When you create the HTTP with Azure AD connection and you don’t choose the gateway, you are required to enter the Azure AD resource URI which you obviously don’t have. When you choose the gateway, you get to specify the base URL, authentication type (choose anonymous) and the connector will work fine.

I then tried to call their on-premises authorization server to obtain the token for the API via client_credentials flow… And there it was, I got the token! Cool!

Next up, was the need to make the actual call to customer’s API. So I parsed the JSON response from the token endpoint, added the token into the Authorization: Bearer <token> header and made the call which went through the gateway and retrieved the data!

So a story with a good ending. I was honestly surprised that a connector called HTTP with Azure AD (I already used the connector in past to call Azure AD protected APIs in the cloud) would let me call on-premises REST API via the on-premises data gateway. Obviously, if you don’t require the use of Authorization header in your on-premises API requests, you are best off with making the custom connector instead.

Comments

Amey

Good findings. I’m also stuck with custom connector with set host policy. When I use this set host policy it looks its not taking on-premises gateway and gives me error as “The remote name could not be resolved:”. But, if I use it without set host policy, it works. Is there any way where we can ask user to select on-premises gateway in connection parameters when we test/incorporate this custom connector in Flow. Please let me know if you have anything around the same. Thanks, Amey

Jan Hájek

Hi there, could you please post some repro steps so I can try? Eventually, feel free to reach out via e-mail - jan.hajek@thenetw.org - will try to do my best to help you out.

caleb

Choosing On Prem now has “Azure AD resource URI” as a mandatory field - so I think this workaround might be outdated now.

Rishi

You mentioned 3 steps 1) Configure connector with anonymous authentication 2) get a token via client credentials 3) call the actual api’s with authorization header.

Just wanted to understand how all 3 steps are connected in PowerApps? How these steps are implemented in PowerApps?

Jens

Thanks for the information. I would like to use this to connect to on-premises interfaces (REST, OData) as backend of a virtual entity.

Is this possible? I can’t find any information about using the On-Premises Data Gateway in combination with virtual entities.

Ravish

I agree with @Caleb response. Choosing On Prem now has “Azure AD resource URI” as a mandatory field and if we don’t give valid value it automatically turns connection to Connect directly (cloud-services).

Dinesh

Awesome!! i have been searching for a solution for a very long time. Earlier I had created a custom connector for the On Prem API and made it to work with token by passing it in the URL query part. But the security team tagged it as a security risk

This solution worked perfectly. Thanks!!

Shwu

Hi,

I have Azure AD post login request. Once successful, it returns the session to be used in the next HTTP request. Is there anyway that I could pass session to the next Azure AD in the header from previous Azure AD? The session is being massaged by the data gateway and was invalid in the second Azure AD request.

Anirban Dutta

I tried the same solution but when users open the power app they are prompted to enter the resource URL. How to overcome that?

To submit comments, go to GitHub Discussions.