Create a Custom Connector for Azure AD protected Azure Functions
A key principle with Power Apps connectors that use Azure Active Directory (AAD) for authentication is that they don't provide users with access to any data that the user doesn't already have access to. This is because the API call to the AAD protected service executes under the user identity used to log in to the connector. Therefore, the target service maintains responsibility for enforcing what is permitted for the authenticated user.
This tutorial shows you how to use Azure Functions to build a REST API, enable AAD authentication, and then make it available to Power Apps as a Custom Connector.
Create Azure Functions using Visual Studio Code
With Azure Functions, there are many options to consider including hosting options, language choice, and authoring options such as using the Azure Portal, Visual Studio Code, Visual Studio, and so on. For this tutorial, we'll use C# and Visual Studio code. To complete this tutorial, you must first complete the Quickstart: Create an Azure Functions project using Visual Studio Code tutorial. Make note of the name you provided for your Function App in the Publish the project to Azure step.
Important
Do not complete the Clean up resources section. You'll need to keep all your resources in place to build on what you've already done.
Protect calls to Azure Functions using AAD
Find your Function App in the Azure Portal. Select the name of your Function App in the list.

In the top section, switch to the Platform features tab,

Next, from the Networking group, select the Authentication / Authorization link.

On the Authentication / Authorization blade, enable App Service Authentication by switching the App Service Authentication toggle button to On.

In the Action to take when request not authenticated drop down, change the value to Log in with Azure Active Directory. This setting ensures that anonymous requests to the API aren't allowed.

Next, in the list of authentication providers, select Azure Active Directory.

In the Azure Active Directory Settings blade, set the Management mode option to Express. Set the second Management mode option to Create New AD App.

Important
Before you continue, note the value in the Create App field and copy/paste it somewhere for later. This value represents the name of the AAD application that you'll use to secure the API. You'll use this value later when you configure your Custom Connector.
Select the OK button to confirm your selection.
Back in the Authentication / Authorization blade, select Save to update the Function App's authentication and authorization settings.

After saving, select Azure Active Directory in the Authentication Providers section.

Select the Azure AD App, then copy the Client Id value and paste it somewhere for use later.

Confirm that the API is correctly secured by opening a new browser window in private mode and navigating to the API. The URL for your Function App can be found in the Overview section of the Function App blade. If the authentication settings have been applied correctly, you should be redirected to the Azure AD login page.

Create a Custom Connector for your Azure Function
To create a Custom Connector that uses AAD authentication, you must create an AAD app registration to secure the Custom Connector and acquire delegated access to the Azure Functions protected by the AAD app registration created in the Protect calls to Azure Functions using AAD section.
Create an app registration for your Custom Connector in AAD
First, create an AAD application for your Custom Connector. This is required to grant the Custom Connector permission to call your Azure Functions.
Navigate to the App registrations page in the Azure Portal.

In the list of registered applications, select New registration.

Enter a name for your application, select the options shown in the screenshot below, and then select the Register button.

Note
To learn more about app registration options, see Quickstart: Register an application with the Microsoft identity platform.
After selecting the Register button, you will be shown API permissions for your App registration.

Select the Add a permission button.

Select the APIs my organization uses tab, then search for the app name from step 7 in the Protect calls to Azure Functions using AAD section. When you find it, click the name of the app.
Important
Your app name will be different than what's in the screenshot.

Select the user_impersonation checkbox and click the Add permissions button.

Note
To learn more about permissions, see Permissions and consent in the Microsoft identity platform endpoint.
Select Certificates & secrets, then select the New client secret button.

Enter a description for your secret, select an expiration period, and then select Add.

Your new secret is displayed. Copy and paste the value somewhere. You'll need it later.

Select Overview, then copy and paste the value of the Application (client) ID somewhere. You'll need it later.

Keep this page open so you can come back to it. There is one more step in the Azure portal, but first you create a custom connector.
Create a custom connector
Now that the AAD application is configured, you create the Custom Connector. To create a Custom Connector, you must describe the API you want to connect to so that the connector understands the API's operations and data structures. When building Azure Functions for Custom Connectors, you will often iteratively build your connector by repeating the following steps:
- Create, test, and debug the Azure Function locally with Visual Studio Code.
- Deploy your Function App to Azure.
- Update the Custom Connector configuration to reflect changes in your Function App.
Postman is a popular tool to test web APIs. It's often used to test Azure Functions. In this topic, you'll create a custom connector from a Postman collection. The Postman collection will be provided for you.
Note
See the Create a Postman collection for a custom connector topic to learn how to create your own. Using Postman to create a Custom Connector is just one option. See the Describe the API and define the custom connector topic to learn about others.
In a new browser tab, sign in to Power Apps or Power Automate.
Copy the code below. Using your favorite text editor, create a new file, and paste the code as the contents of the file. Save the file. You can name it whatever you prefer, but remember the name (ex: tutorial-custom-connector.json). You'll need to use this file in the next steps.
{ "id": "c4b5deba-f97b-47d0-82a5-a2b32561fb01", "name": "Custom Connector", "description": null, "auth": null, "events": null, "variables": [], "order": [ "374365a1-ede5-4ead-8068-d878085dad26" ], "folders_order": [], "protocolProfileBehavior": {}, "folders": [], "requests": [ { "id": "374365a1-ede5-4ead-8068-d878085dad26", "name": "Hello", "url": "http://localhost:7071/api/Hello", "description": "", "data": [], "dataOptions": { "raw": { "language": "json" } }, "dataMode": "raw", "headerData": [ { "key": "Content-Type", "name": "Content-Type", "value": "application/json", "description": "", "type": "text" } ], "method": "POST", "pathVariableData": [], "queryParams": [], "auth": null, "events": null, "folder": null, "responses": [ { "id": "46baba58-7b85-4a2e-8c7d-303080e08ba9", "name": "Hello", "status": null, "mime": null, "language": "plain", "text": "Hello, Marc. This HTTP triggered function executed successfully.", "responseCode": { "code": 200, "name": "OK" }, "requestObject": { "data": [], "dataMode": "raw", "dataOptions": { "raw": { "language": "json" } }, "headerData": [ { "key": "Content-Type", "name": "Content-Type", "value": "application/json", "description": "", "type": "text" } ], "method": "POST", "pathVariableData": [], "queryParams": [], "url": "http://localhost:7071/api/Hello", "rawModeData": "{\n\t\"name\": \"Marc\"\n}" }, "headers": [ { "key": "Date", "value": "Wed, 04 Mar 2020 22:32:06 GMT" }, { "key": "Content-Type", "value": "text/plain; charset=utf-8" }, { "key": "Server", "value": "Kestrel" }, { "key": "Transfer-Encoding", "value": "chunked" } ], "cookies": null, "request": "374365a1-ede5-4ead-8068-d878085dad26", "collection": "c4b5deba-f97b-47d0-82a5-a2b32561fb01" } ], "rawModeData": "{\n\t\"name\": \"Marc\"\n}", "headers": "Content-Type: application/json\n", "pathVariables": {} } ] }In the navigation pane, select Data to expand it, then select Custom Connectors.

In the upper right corner, select New custom connector, then Import a Postman collection.

Enter a name for the connector, select the Import button, browse to the file you created in step 2, then select Continue.

The General page opens. Change the Scheme to HTTPS, replace the Host value with the domain of your Function App, and then advance the wizard to the Security page.

On the Security page, provide AAD information for the application.
For Client id, enter the Application (client) ID value you copied in step 11 in the Create an app registration for your Custom Connector in AAD.
For Client secret, enter the secret value you copied in step 11 in the Create an app registration for your Custom Connector in AAD.
For Resource URL, enter the URL of your Function App. It will be in the format of
https://[function-app-name].azurewebsites.net.

After entering security information, select the Update connector button to create the Custom Connector.
On the Security page, the Redirect URL field is now populated. Copy this URL so you can use it in the next section of this tutorial.
Note
You may need to scroll down to see the Redirect URL.

In another browser tab, return to the the app registration you created in the Create an app registration for your Custom Connector in AAD section. Make sure you're in Overview section, then select Add a Redirect URI.

Select the Add a platform button.

In the Configure platforms pane, select Web.

In the Configure Web pane, paste the Redirect URL value from step 7, then select the Configure button.

Return to the browser tab containing the Custom Connector configuration. You should still be on the Security page in the wizard.
Advance to the Definition page in the wizard by selecting the word Definition and review.

Note
The Definition comes from the Postman collection you imported. If you changed any of the code in the Quickstart: Create an Azure Functions project using Visual Studio Code tutorial, the import file might not match the shape of your API. You'll either need to create a new Postman collection or manually adjust the action in the Custom Connector. To create a new Postman collection, use the links shared earlier in this tutorial here. To manually adjust the action, you can review the Create the connector definition section of the Create a custom connector from scratch tutorial.
Test the connector
Now that you've created the connector, test it to make sure it's working properly. Testing is currently available only in Power Automate and Power Apps.
Advance to the Test page in the wizard by selecting the word Test.

On the Test page, select New connection.

Select the Create button, then log in with your AAD user.

Return to the Test page.
In Power Automate, you're taken back to the Test page. Choose the refresh icon to make sure the connection information is updated.

In Power Apps, you're taken to the list of connections available in the current environment. In the navigation pane, select Custom Connectors. Find your Custom Connector an select the edit icon.

Navigate back to the Test page, enter a value for the name field, then select Test operation.

Review the Request and Response.


Next steps
Now that you've created a custom connector and defined its behaviors, you can use the connector.