This sample project demonstrates how to create an Azure Function with an HTTP trigger and OAuth2 authentication using Azure Active Directory (AAD).
When functions use an HTTP trigger, you can require calls to first be authenticated. Azure Functions supports multiple authentication providers, including Azure Active Directory (Azure AD), Facebook, Google, Twitter, and Microsoft Account. You can also use custom authentication providers.
- Clone this repository.
- Open the repository in Visual Studio Code.
- Reopen the repository in the Dev Container.
- Run the following command to install the dependencies.
npm install
- Run the following command to start the Azure Function.
npm start
The default Dev Container in VS Code is configured to deploy the Azure Functions to Azure.
To deploy the Azure Function, right-click on the Function App
group in the Azure
resources view and select Create Function App in Azure...
. Then follow the instructions to deploy the Function in your Azure subscription.
To deploy the Azure Function, open Azure
tab in your VS Code,
click on the function logo in the Workspace
view and select Deploy to Function App...
. Then follow the instructions to deploy the Function in your Azure subscription.
After successful deployment, you can access the Azure Function in the Azure portal.
To configure OAuth2 authentication, you need to create an OAuth2 application in the Azure Active Directory (AAD) and configure the Azure Function to use the AAD application.
- Open the Azure portal.
- Navigate to the Azure Function App that you have created.
- In the
Settings
section, click onAuthentication
and then click onAdd identity provider
. - In the
Choose a tenant for your application and its users
section, selectWorkforce configuration (current tenant)
. - In the
App registration
section, you can either create a new app registration or select an existing app registration. If you want to create a new app registration, you can specify the appName
, and select theSupported account types
asCurrent tenant - Single tenant
. - In the
App Service authentication settings
section, make sure that theRestrict access
is set toRequire authentication
. - In the
Unauthenticated requests
section, selectHTTP 401 Unauthorized: recommended for APIs
. - Click Next and then click Add.
- From the portal menu, select Microsoft Entra ID.
- From the left navigation, select App registrations > New registration.
- In the Register an application page, enter a Name for your app registration.
- For a daemon application, you don't need a Redirect URI so you can keep that empty.
- Select Register.
- After the app registration is created, copy the value of Application (client) ID.
- From the left navigation, select Certificates & secrets > Client secrets > New client secret.
- Enter a description and expiration and select Add.
- In the Value field, copy the client secret value. It won't be shown again once you navigate away from this page.
Open up a browser, Iโd recommend in incognito/in-private mode. We now need to build up a specific URL to call MS Identity and authenticate. All of the below should be on one line, but has been broken over multiple lines so it is easier to read.
https://login.microsoftonline.com/<Tenant ID>/oauth2/v2.0/authorize
?client_id=<Client ID>
&response_type=code
&redirect_uri=https%3A%2F%2F<Function Name>.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback
&response_mode=fragment
&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&state=12345
Once you have the URL, paste it into the browser and hit enter. You will be redirected to the Microsoft login page. Enter your credentials and sign in. You will then be redirected to the Azure Function.
After successful authentication, you will be able to execute the Azure Function.
You can use the following sample client application to test the OAuth2 authentication.
const fetch = require('node-fetch');
const tenantId = '<Tenant ID>';
const clientId = '<Client ID>';
const clientSecret = '<Client Secret>';
const form = {
client_id: clientId,
client_secret: clientSecret,
grant_type: 'client_credentials',
scope: 'api://<Application ID>/.default'
};
let formBody = [];
for (const property in form) {
const encodedKey = encodeURIComponent(property);
const encodedValue = encodeURIComponent(form[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
const response = await fetch(`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
body: formBody
});
const data = await response.json();
const token = data.access_token;
console.log(token);
const fetch = require('node-fetch');
const token = '<Access Token>';
const response = await fetch('https://<Function App Name>.azurewebsites.net/api/<Function Name>', {
method: 'GET',
headers: { Authorization: `Bearer ${token}` }
});
const data = await response.json();
console.log(data);