Tested out the Azure AD B2C PKCE Authorization Code Flow in Postman. You can follow the tutorial and example below:
Postman workspace example
Public docs
Tag Archives: AzureAD
Automating Azure Privileged Identity Management (PIM) with PowerShell
On a recent support case we had a customer who was trying to automate Privileged Identity Management (PIM) role assignments for Azure Resources with PowerShell. We could not find any public end to end documentation on the syntax to make this work. After some trial and error we found the following syntax works.
NOTE: PIM can assign both Azure AD roles and Azure resource roles so both scenarios are shown below. Additionally, make sure you have the latest version of AzureADPreview module installed.
Assigning Azure AD roles
For this scenario there is a public doc explaining the syntax which can be found at PowerShell for Azure AD roles in Privileged Identity Management . For roleDefinitionID you can also look these IDs up on Azure AD built-in roles doc
PowerShell code example:
### Azure AD PIM Example Connect-AzureAD $tenantID = "91ceb514-5ead-468c-a6ae-048e103d57f0" $roleDisplayName = "Global Administrator" $roleDefinitionID = (Get-AzureADMSRoleDefinition -Filter "DisplayName eq '$roleDisplayName'").Id $targetuserID = (Get-AzureADUser -ObjectId User.Name@jasonfritts.me).ObjectId # Replace user ID $schedule = New-Object Microsoft.Open.MSGraph.Model.AzureADMSPrivilegedSchedule $schedule.Type = "Once" $schedule.StartDateTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") $schedule.EndDateTime = ((Get-Date).AddDays(1)).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") # Create temporary eligible role assignment Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'aadRoles' -ResourceId $tenantID -RoleDefinitionId $roleDefinitionID -SubjectId $targetuserID -Type 'adminAdd' -AssignmentState 'Eligible' -schedule $schedule -reason "testing" # Create temporary active role assignment Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'aadRoles' -ResourceId $tenantID -RoleDefinitionId $roleDefinitionID -SubjectId $targetuserID -Type 'adminAdd' -AssignmentState 'Active' -schedule $schedule -reason "testing"
Assigning Azure Resource Roles
For Azure Resource roles I could not find any end to end public doc examples but after trial and error the below steps were confirmed to work.
NOTE: The additional cmds compared to Azure AD role scenario are to convert ARM subscription IDs and ARM role IDs into their PIM resource IDs. For roleDefinitionID you can also look up built-in role IDs on Azure built-in roles doc if you are using custom roles, you can look these up in Azure Portal -> Subscription blade -> Access Control -> Roles
PowerShell code example:
## Azure Resource PIM Example Connect-AzureAD $subscriptionID = "ed6a63cc-c71c-4bfa-8bf7-c1510b559c72" $roleDefinitionID = "b24988ac-6180-42a0-ab88-20f7382dd24c" #Built-in Contributor Role Definition ID example $targetuserID = (Get-AzureADUser -ObjectId User.Name@jasonfritts.me).ObjectId # Replace user ID # Convert IDs to PIM IDs $SubscriptionPIMID = (Get-AzureADMSPrivilegedResource -ProviderId 'AzureResources' -Filter "ExternalId eq '/subscriptions/$subscriptionID'").Id $RoleDefinitionPIMID = (Get-AzureADMSPrivilegedRoleDefinition -ProviderId 'AzureResources' -Filter "ExternalId eq '/subscriptions/$subscriptionID/providers/Microsoft.Authorization/roleDefinitions/$roleDefinitionID'" -ResourceId $subscriptionPIMID).Id $schedule = New-Object Microsoft.Open.MSGraph.Model.AzureADMSPrivilegedSchedule $schedule.Type = "Once" $schedule.StartDateTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") $schedule.EndDateTime = ((Get-Date).AddDays(1)).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") # Create temporary eligible role assignment Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'AzureResources' -ResourceId $SubscriptionPIMID -RoleDefinitionId $RoleDefinitionPIMID -SubjectId $targetuserID -Type 'adminAdd' -AssignmentState 'Eligible' -schedule $schedule -reason "testing" # Create temporary active role assignment Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'AzureResources' -ResourceId $SubscriptionPIMID -RoleDefinitionId $RoleDefinitionPIMID -SubjectId $targetuserID -Type 'adminAdd' -AssignmentState 'Active' -schedule $schedule -reason "testing"
Assigning Azure AD Graph API Permissions to a Managed Service Identity (MSI)
On a recent support case a customer wished to assign Azure AD Graph API permissions to his Managed Service Identity (MSI). If this was a standard Application Registration, assigning API permissions is quite easy from the portal by following the steps outlined in Azure AD API Permissions. However, today Managed Service Identities are not represented by an Azure AD app registration so granting API permissions is not possible in the Azure AD portal for MSIs.
Luckily, this is possible with the Azure AD and Azure PowerShell modules as well as Azure CLI shown via my colleague Liam Smith’s code samples below:
UPDATED 2020-11-30: Updated to assign graph.microsoft.com app roles instead of the legacy graph.windows.net. Reference https://docs.microsoft.com/en-us/graph/permissions-reference#microsoft-graph-permission-names for list of app roles
Assigning via PowerShell
#First define your environment variables $TenantID="91ceb514-5ead-468c-a6ae-048e103d57f0" $subscriptionID="ed6a63cc-c71c-4bfa-8bf7-c1510b559c72" $DisplayNameOfMSI="AADDS-Client03" $ResourceGroup="AADDS" $VMResourceGroup="AADDS" $VM="AADDS-Client03" #If your User Assigned Identity doesnt exist yet, create it now New-AzUserAssignedIdentity -ResourceGroupName $ResourceGroup -Name $DisplayNameOfMSI #Now use the AzureAD Powershell module to grant the role Connect-AzureAD -TenantId $TenantID #Connected as GA $MSI = (Get-AzureADServicePrincipal -Filter "displayName eq '$DisplayNameOfMSI'") Start-Sleep -Seconds 10 $GraphAppId = "00000002-0000-0000-c000-000000000000" #Windows Azure Active Directory aka graph.windows.net, this is legacy AAD graph and slated to be deprecated $MSGraphAppId = "00000003-0000-0000-c000-000000000000" #Microsoft Graph aka graph.microsoft.com, this is the one you want more than likely. $GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$MSGraphAppId'" $PermissionName = "Directory.Read.All" $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 #NOTE: The above assignment may indicate bad request or indicate failure but it has been noted that the permission assignment still succeeds and you can verify with the following command Get-AzureADServiceAppRoleAssignment -ObjectId $GraphServicePrincipal.ObjectId | Where-Object {$_.PrincipalDisplayName -eq $DisplayNameOfMSI} | fl
At this point you should have been able to verify that your identity’s service principal has the correct app roles as shown below.
You can now perform some tests to verify permissions via the following code on your Azure Virtual Machine that has the service identity assigned to it:
# First grab a bearer token for the Graph API using IMDS endpoint on Azure VM $response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.microsoft.com' -Method GET -Headers @{Metadata="true"} $content = $response.Content | ConvertFrom-Json $token = $content.access_token
You can copy\paste the value of $token to https://jwt.io to verify that your token is showing the Directory.Read.All permission properly.
If for some reason your $token does not show the Directory.Read.All permission, try rebooting your Azure Virtual Machine as it is possible a previous failed request for a bearer token was cached on your VM
Now, continue testing on your Azure VM by using this $token to make a call to Azure AD Graph API :
$output = (Invoke-WebRequest -Uri "https://graph.windows.net/myorganization/users?api-version=1.6" -Method GET -Headers @{Authorization="Bearer $token"}).content $json = ConvertFrom-Json $output $json.value
Your $json.value output should be the successful response of your Azure AD Graph API call. Hope this helps someone!
Assigning via Azure CLI
You can also perform the same steps using Azure CLI and CURL if this is your preferred management environment. See below for Liam’s steps via Azure CLI
#1) Get accesstoken: accessToken=$(az account get-access-token --resource=https://graph.windows.net --query accessToken --output tsv) #2) Define a variable for your tenantID TenantID=mytenant.onmicrosoft.com #3) Confirm access to graph.windows.net: curl "https://graph.windows.net/$TenantID/users?api-version=1.6" -H "Authorization: Bearer $accessToken" #4) Find your managed identity's object ID and assign to a variable (MSIObjectID) az ad sp list --filter "startswith(displayName, 'MyUAI')" | grep objectId MSIObjectID=d910d43b-8886-4bff-90bf-25ee0acb2314 #5) Find the service principal objectID (GraphObjectID) of the "Windows Azure Active Directory" principal in your directory, also confirm the id of the Directory.Read.All oauth2Permission role is 5778995a-e1bf-45b8-affa-663a9f3f4d04 (DirectoryReadAll) az ad sp list --filter "startswith(displayName, 'Windows Azure Active Directory')" GraphObjectID=72405622-433d-4943-a5ad-11a4401d0bd3 DirectoryReadAll=5778995a-e1bf-45b8-affa-663a9f3f4d04 #6) Define your JSON payload json={'"'id'"':'"'$DirectoryReadAll'"','"'principalId'"':'"'$MSIObjectID'"','"'resourceId'"':'"'$GraphObjectID'"'} #7) Give permissions of 'Directory.Read.All' to the service prinicpal: curl "https://graph.windows.net/$TenantID/servicePrincipals/$MSIObjectID/appRoleAssignments?api-version=1.6" -X POST -d "$json" -H "Content-Type: application/json" -H "Authorization: Bearer $accessToken" #8) Verify with read operation curl "https://graph.windows.net/$TenantID/servicePrincipals/$MSIObjectID/appRoleAssignments?api-version=1.6" -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $accessToken" #9) Now you can test on your resource which has managed identity to verify access curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.windows.net' -H Metadata:true accessToken=<accessToken> curl 'https://graph.windows.net/mytenant.onmicrosoft.com/users?api-version=1.6' -H "Authorization: Bearer $accessToken"