Search code examples
azuremicrosoft-graph-apiasp.net-core-webapiazureportal

How to allow Azure App Service (ASP.NET Core Web API) to utilize app registration's API permissions?


I have an app registration in Azure where I set the MS Graph API permissions. For local development I have developed a function to grab the app registration credentials from user secrets as shown:

    private GraphServiceClient GetGraphClientWithManagedIdentityOrDevClient()
    {
        if (_graphServiceClient != null)
            return _graphServiceClient;

        string[] scopes = new[] { "https://graph.microsoft.com/.default" };

        var chainedTokenCredential = GetChainedTokenCredentials();
        _graphServiceClient = new GraphServiceClient(chainedTokenCredential, scopes);

        return _graphServiceClient;
    }

    private ChainedTokenCredential GetChainedTokenCredentials()
    {
        if (_environment.IsDevelopment())
        {
            var tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
            var clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
            var clientSecret = Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");

            var options = new TokenCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
            };

            // https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
            var devClientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);

            var chainedTokenCredential = new ChainedTokenCredential(devClientSecretCredential);

            return chainedTokenCredential;
        }
        else
        {
            return new ChainedTokenCredential(new ManagedIdentityCredential());
        }
    }

However I have deployed my ASP.NET Core Web API to an app service in Azure portal. When I run the API when deployed, it does not allow me to send an email similar to my local code so I am confident it is a permissions issue. My app service is set to managed identity. However I am not sure how to actually get my application in the app service to connect to the app registration in azure so the API can use the user and permissions to send the email.

UPDATE (1/24/2024) -

Based on the given response below I have put together the following powershell command but its unclear if these assignments of variables are correct:

$params = @{
    principalId = "6f5ndfasfasdfasfdf228"  <—— from app service managed identity tab
    resourceId = "a5cd32asdfdasdfsafasfd5db”. <——from enterprise page of app registration
    appRoleId = "6f5ndfasfasdfasfdf228" <—— from app service managed identity tab
}
$servicePrincipalId = “6f5ndfasfasdfasfdf228”  <—— from app service managed identity tab

New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipalId -BodyParameter $params

If i do run this I now get ew-MgServicePrincipalAppRoleAssignment_Create: Insufficient privileges to complete the operation.


Solution

  • In order to get the app service to communicate with the app registration and utilize its ms graph api permissions through managed identities you need to enable the following api permissions in the app registration page first:

    AppRoleAssignment.ReadWrite.All and Application.Read.All, AppRoleAssignment.ReadWrite.All and Directory.Read.All
    

    Also in the app registration page click app roles and create a role and choose an allowed member type that includes application and be sure to enable that app role in the checkbox at the bottom.

    Go to powershell and do the following individual commands

    Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All, Application.Read.All"
    
    $params = @{
        principalId = “<App Service -> Managed Identity -> Object (principal) ID>”
        resourceId = “<Enterprise Applications -> Properties -> Object ID>”
        appRoleId = “<App Registration -> Manifest -> appRoles -> Id of that created App Role you did in first step>”
    }
    
    $servicePrincipalId = “<Use the same value as you did in principalId in the $params variable above>”
    
    New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipalId -BodyParameter $params
    

    This will now allow the app service to utilize the api permissions of the app registration using that app role you created and managed identities.