Search code examples
azure-ad-b2cazure-managed-identityazure-service-principal

Can We Use SPN identity for creating MSAL token? in C# Don't want use Token


I have tried to create MSAL token for my demon application. I have tried blow code

IManagedIdentityApplication mi = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.WithUserAssignedClientId("myspnid"))
.Build();

              AuthenticationResult result = await mi.AcquireTokenForManagedIdentity("https://graph.microsoft.com/.default")
                  .ExecuteAsync()
                  .ConfigureAwait(false);
              _logger.LogInformation("C# HTTP trigger function processed a request."+ result.AccessToken);
              return new OkObjectResult("Welcome to Azure Functions! token" + result.AccessToken);
          }
          catch (Exception ex)
          {
              return new OkObjectResult("Welcome to Azure Functions! error"+ex.Message);
              _logger.LogInformation("C# HTTP trigger function processed a request." +ex.Message);

          }

I don't want to use secrets. Cos I already have created app I have SPN service principle ID.

can any one have idea on this?

I m adding more details for more clarity

enter image description here

I m using this client id and added full permission for for graph Error is "No User Assigned or Delegated Managed Identity found for specified ClientId/ResourceId/PrincipalId."


Solution

  • To use SPN identity for creating MSAL token/Access token, check the below:

    For sample, I used the below PowerShell script to assign permissions to the managed identity:

    Connect-AzureAD
    
    $TenantID="TenantID"
    $GraphAppId = "00000003-0000-0000-c000-000000000000" 
    $NameOfMSI="ruktestMI"
    $PermissionName = "User.Read.All"
    
    $MSI = (Get-AzureADServicePrincipal -Filter "displayName eq '$NameOfMSI'")
    Start-Sleep -Seconds 10
    $GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'"
    $AppRole = $GraphServicePrincipal.AppRoles | 
    Where-Object {$_.Value -eq $PermissionName -and $_.AllowedMemberTypes -contains "Application"}
    
    New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id
    

    enter image description here

    enter image description here

    Now to generate token, you can make use of below code as a workaround:

    using System;
    using Azure.Identity;
    using Azure.Core;
    
    class Program
    {
        static async Task Main(string[] args)
        {
            string clientId = "XXXX"; // The Client ID of the user assigned identity
    
            AccessToken token = await new DefaultAzureCredential(
                new DefaultAzureCredentialOptions
                {
                    ManagedIdentityClientId = clientId
                })
                .GetTokenAsync(
                    new TokenRequestContext(
                        new[] { "https://graph.microsoft.com/.default" }
                    ));
    
            Console.WriteLine(token.Token);
        }
    }
    

    enter image description here

    By using the above access token, you can call Microsoft Graph API

    Note that: Either make use of Managed identity or interactive flow ( without passing the client secret). OR make use of ROPC flow which is non interactive and doesnt need client Secret to generate token. Using SPN identity and without client secret and non interactively it is not possible to generate token.

    Reference:

    Options for obtaining an access token with Azure application to application authentication by Anoop