0

I am currently using Basic authentication between Azure Function and Web API. This is not secure, hence I was searching for an alternative and found the managed identity feature in Azure. However, I do not see this feature can be enabled between Web API and Azure function.

Note: We can enable between Azure Function and KeyVault but not between web API and azure function.

Looking for a solution like below

enter image description here

kudlatiger
  • 3,028
  • 8
  • 48
  • 98
  • 1
    So you want to use Azure Function managed identity to access Web API instead of using Basic authentication ? – Stanley Gong Mar 03 '21 at 04:11
  • @StanleyGong Yes, exactly. – kudlatiger Mar 03 '21 at 05:13
  • 1
    If so, I think you can use EasyAuth(by Azure AD) to protect your Azure Web API: https://www.c-sharpcorner.com/article/how-to-secure-your-azure-app-service-with-azures-ad-authentication/ so that your Web API will be protected by Azure AD. With this step is done, your function side could use managed identity to get an access token to access your web API – Stanley Gong Mar 03 '21 at 05:23
  • Let me give a try and keep you posted. – kudlatiger Mar 03 '21 at 06:14
  • no prob, take your time – Stanley Gong Mar 03 '21 at 06:18
  • Part 2 of your solution - "your function side could use managed identity to get an access token to access your web API" - do we have an article that shows how do I pass the access token to all requests to web API? – kudlatiger Mar 03 '21 at 09:02
  • 1
    Yes, you can just refer to this doc : https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?context=%2Fazure%2Factive-directory%2Fmanaged-identities-azure-resources%2Fcontext%2Fmsi-context&tabs=dotnet#obtain-tokens-for-azure-resources when you trying to get an access token, the only thing that you need to do is change the resource param as your Azure AD App ID whcih you configed EasyAuth for your web API. Let me know if you have any questions :) – Stanley Gong Mar 04 '21 at 02:44
  • I was able to configure EasyAuth on web API, However, I am getting an idea of how to send a token from AD and send it as part of the request while calling the API. Could u show some sample links? if i understand currectly, I need to have application ID and client ID to get the token from AD. – kudlatiger Mar 06 '21 at 07:35
  • May I know your programming language? I'll write a demo about using managed identity to get an access token to call your Web Api whcih protected by Eay Auth. – Stanley Gong Mar 06 '21 at 11:44
  • My programming language is C# – kudlatiger Mar 08 '21 at 04:01
  • How's going? Has your issue got resolved? – Stanley Gong Mar 08 '21 at 07:26
  • Yes, working on it. Keep you posted in few hours as stuck with org level meetings. solution sounds promising – kudlatiger Mar 08 '21 at 08:45
  • Sure, take your time – Stanley Gong Mar 08 '21 at 08:47
  • added the diagram, so that it helps the reader. @StanleyGong please review the design diagram – kudlatiger Mar 08 '21 at 11:03
  • 1
    That is exactly the solution I provided. So is my code and solution helpful? If it helps, could you please mark it as an answer? – Stanley Gong Mar 09 '21 at 02:24
  • appreciated your time. – kudlatiger Mar 09 '21 at 14:56

2 Answers2

1

I have enabled Easy Auth for my app service : enter image description here

You can find its client ID in advanced blade: enter image description here

So we need to get an access token for this resource to call APIs, just try the code below(I assume you have enabled Managed identity for your function):

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");
    var endpoint = Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT");
    var identity_header = Environment.GetEnvironmentVariable("IDENTITY_HEADER");
    //chnage your client ID value here.
    var resource = "4df52c7e-3d6f-4865-a499-cebbb2f79d26";
    var requestURL = endpoint + "?resource=" + resource + "&api-version=2019-08-01";

    HttpClient httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("X-IDENTITY-HEADER", identity_header);
    HttpResponseMessage response = await httpClient.GetAsync(requestURL);
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    var access_token = JsonConvert.DeserializeObject<TokenResp>(responseBody).access_token;

    //After get access token for app: 4df52c7e-3d6f-4865-a499-cebbb2f79d26, call the API that protected by it
    //chnage your api url here.
    var APIURL = "https://frankapp.azurewebsites.net";
    HttpClient callAPI = new HttpClient();
    callAPI.DefaultRequestHeaders.Add("Authorization","Bearer "+ access_token);
    HttpResponseMessage APIResponse = await callAPI.GetAsync(APIURL);
    //check the response code to see if called the API successfully.
    return new OkObjectResult(APIResponse.StatusCode);
}

public class TokenResp {
 public string access_token { get; set; }
 public string expires_on { get; set; }
 public string resource { get; set; }
 public string token_type { get; set; }
 public string client_id { get; set; }

}

Result:

enter image description here

Stanley Gong
  • 11,522
  • 1
  • 8
  • 16
0

Hi i can see you asking exchange between of Azure Function and Web API, in theory , it should be your resource server(Apis) rather than managed identity. There are concept around on-behalf auth/client grant credential on top of Azure AD. You may follow this learning tutorial Build Azure functions with Microsoft Graph , and start thinking how would you want your identity flow looks like - simple way is to using on-behalf to azure functions and web api, the access token assertion are implemented in common classes for both.

Turbot
  • 5,095
  • 1
  • 22
  • 30