1
votes

We have two azure resources in the same directory. A webAPI set of APIs behind Azure API Management and an Azure Function. We want the azure function to be able to call the APIs. We've enabled MSI on the azure function as described in How to use managed identities for App Service and Azure Functions. We've created an App Registration in AAD for the API, created a role permission to be accessed. Following Calling your APIs with Azure AD Managed Service Identity using application permissions we run into errors attempting to assign the permission/role to the azure function: in powershell:

New-AzureADServiceAppRoleAssignment -ObjectId 8XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -Id 3XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -PrincipalId 8XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -ResourceId 9XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

New-AzureADServiceAppRoleAssignment : Error occurred while executing NewServicePrincipalAppRoleAssignment
Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.
HttpStatusCode: Forbidden
HttpStatusDescription: Forbidden
HttpResponseStatus: Completed
At line:1 char:1
+ New-AzureADServiceAppRoleAssignment -ObjectId 8XXXXXX-XXXX-XXXX-XXXX ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-AzureADServiceAppRoleAssignment], ApiException
    + FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.NewServ
   icePrincipalAppRoleAssignment

is giving us a permission error, even when an AAD Admin (member of AAD DC Administrators I think) runs it. Has anyone run into this before? Why is this throwing a permissions error? We have verified that the ids are correct with 3 different people.

1

1 Answers

1
votes

The problem you're probably facing is that, despite naming your app registration the same thing as your MSI-enabled app, the two end up representing different service principals in AAD. Using app registrations with MSI isn't currently supported.

Try running the powershell commands using the object id of the MSI identity instead. I was able to get this to work, and granted my MSI-enabled app access to the Graph Api.

Here is the PS I used to assign the GraphApi roles my function app required:

$functionAppName = "My-FANCY-FUNC"

$context = Get-AzureRmContext -ErrorAction SilentlyContinue #this lets you search AAD for func

if(!$context){
    $login = Connect-AzureRmAccount  | Out-Null
    Connect-AzureAD #needed this for Graph API
    $context = $login
} else { Write-Host "Login session already established for " $context.Subscription.SubscriptionName }

#get the SP associated with the MSI
$MSIPrincipal = Get-AzureRmADServicePrincipal -SearchString $functionAppName | Where-Object DisplayName -eq $functionAppName

#get the SP associatesd with the MS Graph
$graph = Get-AzureADServicePrincipal -All $true | ? { $_.DisplayName -match "Microsoft Graph" }

#find the target app roles in the graph
$targetRoles = $graph.AppRoles | Where-Object Value -in "Group.ReadWrite.All", "Directory.ReadWrite.All"

#iterate throgh the known roles and add the MSI SP to them
$targetRoles | ForEach-Object {New-AzureADServiceAppRoleAssignment -Id $_.Id -PrincipalId $MSIPrincipal.Id -ObjectId $MSIPrincipal.Id -ResourceId $graph.ObjectId}

I suspect, based on your question, that this line will return more than one entity:

Get-AzureRmADServicePrincipal -SearchString $functionAppName | Where-Object DisplayName -eq $functionAppName

Deleting your extraneous app registration should clear that up