Trouble Implementing Federated Credentials with Managed Identities in Azure Function App API Authentication

Dheepssika JL 0 Reputation points Microsoft Employee
2024-04-22T18:40:22.54+00:00

I have an API inside my function app and have been accessing the API using the secrets created in the app registration associated with the function app. Now we're looking to eliminate the secrets and modify it to use managed idenities as the client app accessing will also be from ms azure. So I came across the federated credentials and thought to use this. I created a client function app and a managed identity associated with this function app. For the API function app's app registration I created a federated credential linking it to the managed identity of my client's function app. Now to test it, using .net from the client app, I am trying to get a token, and add it to the request header and call the API. But the token I get is incorrect and gives me a 401 when I try to access the API. I am not sure if I am missing something in my code, but it would be great if anyone can help me.

I am guessing the URL that am using to get the token is incorrect, but not sure. I tried with multiple other URLs as well but still getting a 401. If you can think of any other alternate ways to replace the secrets by managed identities please me know.

Here's the code -

public async Task<string> GetAccessTokenAsync(string clientId)
{          
    string userAssignedClientId = clientId;
    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });
    var accessTokenRequestContext = new TokenRequestContext(new[] { "api://AzureADTokenExchange" });
    var accessToken = credential.GetToken(accessTokenRequestContext);
    return accessToken.Token;
}

[Function("ClientFunction")]
public async Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
{
    HttpClient _httpClient = new HttpClient();
    var msiClientId = "{client id of my managed identity}";
    var apiUrl = "https://{apiurl}";            
    try
    {
        var token = await GetAccessTokenAsync(msiClientId);
        if (String.IsNullOrEmpty(token))
            _logger.LogInformation("Token is empty");
        else
        {                    
            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiUrl);                   
            HttpResponseMessage response = await _httpClient.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {
                _logger.LogInformation("Api response " + await response.Content.ReadAsStringAsync());                        
            }
            else
            {
                _logger.LogInformation("Request failed " + response.StatusCode);
                string errorResponse = await response.Content.ReadAsStringAsync();                     
                _logger.LogInformation("Error Response: " + errorResponse);
            }
        }
        return new OkObjectResult("end");
    }
    catch (MsalServiceException ex)
    {
        _logger.LogError($"Authentication failed: {ex.Message}");
        return new BadRequestResult(); 
    }
    catch (HttpRequestException ex)
    {                
        _logger.LogError($"HTTP request failed: {ex.Message}");
        return new BadRequestResult();
    }
}
Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,298 questions
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,395 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,559 questions
0 comments No comments
{count} votes