bryniek
bryniek

Reputation: 141

Read AD group from azure function using service principal authentication

I want to read and list members of a particular AD group using powershell script using azure function. To connect AD i am using service principal. Connecting to AzureAD is successful, but trying to access AD group gives me an error (at this stage i just want to get a specific group and echo it):

System.Management.Automation.RemoteException: Error occurred while executing GetGroups 
Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.
RequestId: <requestID>
DateTimeStamp: Mon, 14 Oct 2019 20:40:26 GMT
HttpStatusCode: Forbidden
HttpStatusDescription: Forbidden
HttpResponseStatus: Completed

Why is that happening? did anyone use azuread module commands within azure function? I have granted ms graph permissions for this app: enter image description here

$Script={
    param ()
    ##Save AzureAD module to the modules folder before publishing
    Import-Module .\modules\AzureAD

    $appId = "<AppId>"
    $thumb = "<CertThumb>"
    $tenantId = "TenantID"
    Connect-AzureAD -TenantId $tenantId -ApplicationId  $appId -CertificateThumbprint $thumb

    $groupName = "<Name of the group>"

    $group = Get-AzureADGroup -SearchString $groupName 
    #or
    #$group = Get-AzureADGroup -ObjectId "<object id>"

    echo $group
}

&$env:64bitPowerShellPath -WindowStyle Hidden -NonInteractive -Command $Script

Note that my code is wrapped into $Script variable and last line is added to make the code work as a temporary workaround until AD modul will be added to PS Core: https://github.com/Azure/azure-functions-powershell-worker/issues/232

Upvotes: 1

Views: 4043

Answers (2)

Joy Wang
Joy Wang

Reputation: 42063

As mentioned in another reply, adding the service principal as a directory role is one way, but you should note it will give your service principal other permissions, e.g. create group, delete group.

Actually the issue was caused by you grant the wrong permission, you need to grant the Azure Active Directory Graph with Directory.Read.All Application permission instead of Microsoft Graph, because the command Get-AzureADGroup essentially calls the Azure Active Directory Graph.

enter image description here

Note: When test the command in local, after granting the permission, close your powershell session and open a new one, login again and run the command. If you run that in function, maybe restart the function app to make sure the permission has affected.

Upvotes: 1

Jim Xu
Jim Xu

Reputation: 23111

According to the picture you provided, you have assigned some graph API permissions to the service principal. After you do that, you just can call some graph API with the service principal. If you want to use Azure AD PowerShell module with service principal to manage Azure AD, you need to assign Azure AD role to the service principal. For more details, please refer to https://learn.microsoft.com/en-us/powershell/azure/active-directory/signing-in-service-principal?view=azureadps-2.0.

Regarding how to create service principal and assign role, please refer to the following script.

# Login to Azure AD PowerShell With Admin Account
Connect-AzureAD 

# Create the self signed cert
$currentDate = Get-Date
$endDate  = $currentDate.AddYears(1)
$notAfter  = $endDate.AddYears(1)
$pwd  = "<password>"
$thumb = (New-SelfSignedCertificate -CertStoreLocation cert:\localmachine\my -DnsName com.foo.bar -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $notAfter).Thumbprint
$pwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText
Export-PfxCertificate -cert "cert:\localmachine\my\$thumb" -FilePath c:\temp\examplecert.pfx -Password $pwd

# Load the certificate
$cert  = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("C:\temp\examplecert.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())


# Create the Azure Active Directory Application
$application = New-AzureADApplication -DisplayName "test123" -IdentifierUris "https://test123"
New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier "Test123" -StartDate $currentDate -EndDate $endDate -Type AsymmetricX509Cert -Usage Verify -Value $keyValue

# Create the Service Principal and connect it to the Application
$sp = New-AzureADServicePrincipal -AppId $application.AppId

# Give the Service Principal Reader access to the current tenant (Get-AzureADDirectoryRole)
#Regarding the Azure AD role, please refer to https://learn.microsoft.com/en-us/azure/active-directory/users-groups-roles/roles-delegate-by-task
$role = Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "role name"}
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $sp.ObjectId

Upvotes: 0

Related Questions