This page describes how to add Application app roles to an application in Azure Active Directory using the manifest.
Code sample from the page:
"appId": "8763f1c4-f988-489c-a51e-158e9ef97d6a",
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"displayName": "ConsumerApps",
"id": "47fbb575-859a-4941-89c9-0f7a6c30beac",
"isEnabled": true,
"description": "Consumer apps have access to the consumer data.",
"value": "Consumer"
}
],
"availableToOtherTenants": false,
When calling an an Azure Function from an application authenticated using the client_credentials
grant type, how do you enforce it to belong to the application role?
I've Googled but been unable to find clear documentation that explains how this authorization is done for Azure Functions.
My Test Function App
I've created a simple "hello <name>" Azure Function from within the Azure Portal which I call from Postman.
#r "Microsoft.Azure.WebJobs.Extensions.Http"
#r "Newtonsoft.Json"
using System.Net;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
public static IActionResult Run(HttpRequest req, ILogger log, ClaimsPrincipal claimsPrincipal)
{
var name = req.Query["name"];
log.LogInformation($"C# HTTP trigger function processed a request: {name}");
var cp = new {
Identity = new {
claimsPrincipal.Identity.AuthenticationType,
claimsPrincipal.Identity.IsAuthenticated,
claimsPrincipal.Identity.Name
},
Claims = claimsPrincipal.Claims.Select(claim => new
{
claim.Type,
claim.Value
})
};
log.LogInformation($"ClaimsPrincipal ({claimsPrincipal.GetType().FullName}): {JsonConvert.SerializeObject(cp, Formatting.Indented)}");
return (IActionResult)new OkObjectResult($"Hello, {name}");
}
Firstly I authenticate using https://login.microsoftonline.com/<Tenant ID>/oauth2/v2.0/token
and capture the access_token
.
Request Body Example:
grant_type:client_credentials
client_id:<Application ID>
client_secret:<Client Secret>
scope:https://<Function-app-name>.azurewebsites.net/.default
Example Result:
{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599,
"access_token": "eyJ0eXAi......"
}
Then I call my Azure Function using https://<function-app-name>.azurewebsites.net/api/hello?name=World
and a header containing Authorization: Bearer eyJ0eXAi......
.
Authentication works fine, as does calling the Azure Function. However, I can add a new Application via App registrations in the Azure Portal, authenticate and then call the Azure Function freely. I don't know how to restrict access the the Azure Function to only Applications that have a specific application role.