Call SharePoint REST API inside Azure Fucntion on .NET 8 is causing this error "Response status code does not indicate success: 401 (Unauthorized)."

john john Pter 1,015 Reputation points
2025-04-20T20:45:30.8666667+00:00

We have an Azure Function that runs on a scheduled basis, and we have enabled its managed identity. Using this identity, we've successfully integrated the function with both Azure SQL database and Azure Key Vault by assigning the necessary permissions:

M6eyCVlp

We are now looking to integrate the same Azure Function with SharePoint Online, to enable read and write operations to specific site.

We run those commands based on this article from Microsoft @ https://learn.microsoft.com/en-us/sharepoint/dev/apis/webhooks/sharepoint-webhooks-using-azd-template#grant-the-function-app-access-to-sharepoint-online:-

# This script requires the modules Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns, which can be installed with the cmdlet Install-Module below:

# Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns -Scope CurrentUser -Repository PSGallery -Force

Connect-MgGraph -Scope "Application.Read.All", "AppRoleAssignment.ReadWrite.All"

$managedIdentityObjectId = "d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity

$scopeName = "Sites.Selected"

$resourceAppPrincipalObj = Get-MgServicePrincipal -Filter "displayName eq 'Office 365 SharePoint Online'" # SPO

$targetAppPrincipalAppRole = $resourceAppPrincipalObj.AppRoles | ? Value -eq $scopeName

$appRoleAssignment = @{

"principalId" = $managedIdentityObjectId

"resourceId" = $resourceAppPrincipalObj.Id

"appRoleId" = $targetAppPrincipalAppRole.Id

}

New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityObjectId -BodyParameter $appRoleAssignment | Format-List

and

Connect-PnPOnline -Url "https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME" -Interactive -ClientId "YOUR_PNP_APP_CLIENT_ID"

Grant-PnPAzureADAppSitePermission -AppId "3150363e-afbe-421f-9785-9d5404c5ae34" -DisplayName "YOUR_FUNC_APP_NAME" -Permissions Manage

Now we should have granted the Azure function the required permission to access the SharePoint site using SharePoint REST API + Graph API.

I have this code in my Azure Function which uses 2 ways for authenticating:

  1. If I am on my development machine, I will authenticate using the browser
  2. If I am in the Azure Function hosted app, I will authenticate using the Azure Function identity

When I run the project on my development machine, I get this error:-

Response status code does not indicate success: 401 (Unauthorized).

Here is the full code:


    var allItems = new List<CallTransferLogData>();

    while (!string.IsNullOrEmpty(fullUrl))
    {
        var response = await httpClient.GetAsync(fullUrl);
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync();

        using var doc = JsonDocument.Parse(content);
        var root = doc.RootElement.GetProperty("d");

        // Parse items
        var items = root.GetProperty("results");

        foreach (var item in items.EnumerateArray())
        {
            var parsed = new CallTransferLogData
            {
                VID = item.GetProperty("Title").GetString(),
                SRBrokerName = item.GetProperty("field_4").GetString(),
                Log = item.GetProperty("field_5").GetString(),
                YourName = item.GetProperty("field_3").GetString(),
                Email = item.GetProperty("Email").GetString(),
                Timestamp = item.GetProperty("field_0").GetDateTime(),
                IfLogIsTODAYLeaveThisBlank = item.GetProperty("field_2").GetDateTime(),
                SharePointSourceID = item.GetProperty("ID").GetInt32()
            };

            allItems.Add(parsed);
        }

        // Get next page
        fullUrl = root.TryGetProperty("__next", out var nextLink)
            ? nextLink.GetString()
            : null;
    }
   
    if (allItems.Count == 0)
    {
        _logger.LogInformation("No Call Transfer Log Data found.");
        //return;
    }

    //Insert/Update Conversations in SQL Server
    await UpsertCallTransferHistoryLogToSqlServer(allItems);
    _logger.LogInformation("Call Transfer Log Data successfully processed.");
    await SQLInteraction(new Log { Status = "End Call Transfer Log Data TimeJob Execution Successfully" }, false);
}
catch (Exception ex)
{
    _logger.LogError($"Error: {ex.Message}");
    anyexception = true;
    await SendEmail("ATTN Ruben-Azure Function Exception-Call Transfer Log Data", ex.Message, Environment.GetEnvironmentVariable("ToEmailException"));
    await SQLInteraction(new Log { Status = "End Call Transfer Log Data TimeJob with Exception", Exception = ex.Message }, false);
}


Any advice why we get this unauthorized error?

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
13,580 questions
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.