Forum Discussion
Unsupported but very useful way to use the hidden Azure API
- Sep 13, 2018
Fantastic information!!! Thank you for sharing!!
I have discovered COUNTLESS uses for this, from obtaining all of the 'Conditional Access' policies that are configured in AzureAD, to obtaining a list of Azure Gallery/Marketplace Apps that are available as 'Enterprise Apps'.
Thanks again!
Evan
Here a few quick PowerShell samples that I've used previously:
$adalversion = "2.28.4"
$aadgraph = "1.61-internal"
$adal = resolve-path "$pwd\.nuget\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.$adalversion\lib\net45"
[System.Reflection.Assembly]::LoadFrom("$adal\Microsoft.IdentityModel.Clients.ActiveDirectory.dll")
[System.Reflection.Assembly]::LoadFrom("$adal\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll")
And, once you have authenticated properly using the below method (NOTE the specific version of the ADAL client libraries being used!!!) and have your access token, you can create a PowerShell function to retrieve Conditional Access policies, Gallery Apps, Grant Admin Consent to apps programmatically, etc.
Example functions to Get an access token to the 'hidden' API and an example function to retrieve Gallery apps:
Function Get-PortalAPIAccessToken {
param(
[string]$clientId = "1950a258-227b-4e31-a9cf-717495945fc2",
[string]$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
)
$audgid = "74658136-14ec-4630-ad9b-26e160ff0fc6"
$authority = "https://login.microsoftonline.com/<tenant>"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority, $false
$authResult = $authContext.AcquireToken($audgid, $clientId, $redirectUri, 'Auto')
$token = $authResult.AccessToken
return $token;
}
function Get-GalleryApps() {
Param(
[Parameter()]$token,
[Parameter()]$nextLink
)
$global:apps = @()
$header = @{
"Sec-Fetch-Dest" = "empty";
"Sec-Fetch-Mode" = "cors";
"accept-encoding" = "gzip, deflate, br";
"accept-language" = "en";
"x-ms-effective-locale" = "en.en-us"
"Authorization" = "Bearer $token";
"Content-Type" = "application/json";
"x-ms-client-request-id" = (New-Guid).Guid;
"x-ms-session-id" = "12345678910111213141516";
"Accept" = "*/*";
"x-requested-with" = "XMLHttpRequest";
"user-agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3829.0 Safari/537.36 Edg/77.0.197.1";
"method" = "GET"
}
$url = "https://main.iam.ad.ext.azure.com/api/applications/gallery?top=999&nextLink=$nextLink"
$global:res = Invoke-RestMethod -Uri $url -Headers $header -Method GET -ContentType "application/json"
foreach ($global:app in $global:res.items) {
$global:apps += ($global:app | ConvertTo-Json -Compress) -join ","
}
if ($global:res.nextLink) {
$global:apps += ((get-galleryapps -nextLink $global:res.nextLink) | ConvertTo-Json -Compress) -join ","
}
$apps | ConvertTo-Json -Compress | Out-File ".\galleryapplist.json" -Force -Append
return $global:apps
}
I would recommend using method 2 in this post instead, then you don't need DLL's / modules at all: https://www.lieben.nu/liebensraum/2020/04/calling-graph-and-other-apis-silently-for-an-mfa-enabled-account/