Search code examples
c#azureazure-functionsazure-web-app-serviceresource-management

Azure Resource: REST API returns empty response in Deployed Azure Function


Azure REST API return 200 code with an empty response in Deployed azure function.

{
    "value": []
}

I am trying to get all resources from Azure API, API return all resources when debugging from local, But getting empty response when calling from Deployed Azure function. In one of post I got answer, where should I add Azure function identity to get all the resources?


Solution

  • In your local machine, Azure Function is using DefaultAzureCredentials from Azure CLI or your local terminal log in thus you can get Azure Resources list when you call the API locally but not in Azure Function app.

    In order to authenticate with your Function App in portal and get the results you can make use of ClientCredentials authentication with Azure service principal having Contributor role assigned at the Subscription level.

    I used the below code from this SO answer by Vinny and John and this Rest API in my Function1.cs to get all the resources with ClientCredentials flow via Azure Function:-

    using Azure.Core; 
    using Azure.Identity; 
    using Newtonsoft.Json;
    using System; 
    using System.Net.Http; 
    using System.Threading.Tasks; 
    using Azure.Core; using Azure.Identity; 
    using Newtonsoft.Json; 
    using System; 
    using System.Net.Http; 
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http; 
    using Microsoft.AspNetCore.Mvc; 
    using Microsoft.Azure.WebJobs; 
    using Microsoft.Azure.WebJobs.Extensions.Http; 
    using Microsoft.Extensions.Logging; 
    using System.Net.Http.Json;
    
    namespace FunctionApp1 {
        public static class Function1
        {
            [FunctionName("Function1")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
                ILogger log)
            {
                log.LogInformation("C# HTTP trigger function processed a request.");
    
                var token = await GetAccessToken("<tenant-id>", "<client-id>", "<password>");
                var results = await GetResults(token);
    
                return new OkObjectResult(results);
            }
    
            private static async Task<string> GetAccessToken(string tenantId, string clientId, string clientKey)
            {
                var credentials = new ClientSecretCredential(tenantId, clientId, clientKey);
                var result = await credentials.GetTokenAsync(new TokenRequestContext(new[] { "https://management.azure.com/.default"
    }), default);
                return result.Token;
            }
    
            private static async Task<string> GetResults(string token)
            {
                var httpClient = new HttpClient
                {
                    BaseAddress = new Uri("https://management.azure.com/subscriptions/")
                };
    
                string URI = $"0151c365-f598-44d6-b4fd-e2b6e97cb2a7/resources" +
                    $"?api-version=2022-01-01";
    
                httpClient.DefaultRequestHeaders.Remove("Authorization");
                httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
                HttpResponseMessage response = await httpClient.GetAsync(URI);
    
                var HttpsResponse = await response.Content.ReadAsStringAsync();
                //var JSONObject = JsonConvert.DeserializeObject<object>(HttpsResponse);
    
                //return response.StatusCode.ToString();
                return HttpsResponse;
            }
        } } ```
    

    Output:-

    Local:-

    enter image description here

    I deployed the Function to my Azure Portal and received the same output:-

    enter image description here

    enter image description here