0

I have an Azure Static Web App that is configured with AAD, aka Entra ID, authentication. I also have an Azure Function App that I have deployed separately and then linked to the Static Web App as a backend. To be extra clear, this Function App is a linked backend (BYOF), and not a managed function.

I want to be able to call the Microsoft Graph API from the Function App, using delegated permissions from the authentication that is done in the Static Web App, and retrieve user information such as name, surname, email, photo etc. for users based on id.

I have added the delegated permission User.ReadBasic.All to my App Registration for my Static Web App (same one that is used to configure auth).

What else needs to be done to be able to authenticate the Function App against the Microsoft Graph API on behalf of the user of my Static web App?

2
  • Hi Omni i guess, you need to implement the OAuth 2.0 authorization code flow with PKCE (Proof Key for Code Exchange) in your Function App. Commented Jan 3, 2024 at 12:39
  • Hi @MohamedAzarudeenZ. Can you please elaborate? Commented Jan 3, 2024 at 14:31

2 Answers 2

1

I found the other answer to be a little confusing and misleading, so I thought I'd post my own:

It is possible to set up the on-behalf-of flow with Azure Static Web App and Linked Backend (BYOF Function App), but not through the built-in authentication (the one that you set up through the Static Web App config file). This must be done "manually" by using the Microsoft Authentication Library (MSAL).

Microsoft provides a tutorial on how to do this, which can be found in their GitHub repo.

However, I decided to take another path and assign application permissions to my app registration instead, which - unlike delegated permissions - requires admin consent.

I hope this post can be helpful to someone facing the same kind of problem.

Sign up to request clarification or add additional context in comments.

Comments

0

As you are using BYOF, The Function code will work separately and the authentication you are doing in Azure Static Web app will not work. And as Azure Functions cannot run interactive login inside the App, You cannot use User specific flows like Implicit flow or Auth code flow wherever User interaction via Browser login is required.

Here, You need to create one Azure Functions with Client Credentials Flow using Azure service principal- Client Id, Client Secret and Tenant Id like below.

Reference here.

My Function1.cs:-

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", "Client-Secret");
            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://graph.microsoft.com/.default"
}), default);
            return result.Token;
        }

        private static async Task<string> GetResults(string token)
        {
            var httpClient = new HttpClient
            {
                BaseAddress = new Uri("https://graph.microsoft.com/v1.0/")
            };

            string URI = $"users/a8f97275-2685-41ce-a61d-dc550cd090f8";

            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:-

enter image description here

enter image description here

Now, Add this Function in your Azure static web app and call it along with the static web app URL as mentioned in my SO answer.

enter image description here

4 Comments

Hi. If I am not mistaken, your example requires application permissions rather than delegated permissions. Is that correct? I would like to be able to use delegated permissions from the user that signed in to the Static Web App to call the Microsoft Graph API from my Function App, using the on-behalf-of flow. Are you saying that it is not possible using linked backend?
Yes, That's not possible with the BYOF Linked backend function, Cause the Function app and code is created separately. And Its only attached as an API with the static web app. And Function app does not support Interactive login with user, It will only support service principal or managed identity based authentication.
One option is to write Function API code along with your Application and then deploy your code to static web app where by default your API acting as function gets added in the SWA backend
Refer this Blazor with SWA MS Document- where one API is also added, You can refer the same github sample from this doc-learn.microsoft.com/en-us/azure/static-web-apps/deploy-blazor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.