Accessing the backend Azure AD APIs behind portal.azure.com

There are many features that are currently “UI only” with Azure AD, managed through the Azure Portal. However, some times it can be useful to being able to access these things through scripts, such as for auditing or whatever.

Behind the Azure Portal, there are several APIs that are public facing, but undocumented and not meant for being used directly. Follow this guide with caution, as there is things that can go wrong if you start posting or patching to these APIs.

Step 1 – Getting an access token

This is fairly straight forward, as we will use an existing app registration that is present in all tenants, the same app registration used for Azure AD PowerShell and the Azure Portal – application id 1950a258-227b-4e31-a9cf-717495945fc2.

Using this app registration, we can request a token through ROPC, for the resource 74658136-14ec-4630-ad9b-26e160ff0fc6 – which is the same thing done in the Azure Portal.

$tenantid = "f1127665-304a-4177-8fbe-581d52296c77"
$username = "admin@m365x633816.onmicrosoft.com"
$password = "store-this-more-safely-than-this-example"

# Create uri and body
$uri = "https://login.microsoftonline.com/{0}/oauth2/token" -f $tenantid
$body = "resource=74658136-14ec-4630-ad9b-26e160ff0fc6&client_id=1950a258-227b-4e31-a9cf-717495945fc2&grant_type=password&username={1}&password={0}" -f [System.Web.HttpUtility]::UrlEncode($password), $username

# Request token through ROPC
$token = Invoke-RestMethod $uri -Body $body -ContentType "application/x-www-form-urlencoded" -ErrorAction SilentlyContinue

Now we have a token that we can use towards the backend APIs.

Step 2 – Calling an API

One example API endpoint that is not available in the Microsoft Graph, is B2B Policy. The following examples uses the above token, and gets the B2B Policy from the main.iam.ad.ext.azure.com API.

$b2bPolicy = Invoke-RestMethod 'https://main.iam.ad.ext.azure.com/api/B2B/b2bPolicy' -Headers @{Authorization = "Bearer $($token.access_token)"; "x-ms-client-request-id" = [guid]::NewGuid().ToString(); "x-ms-client-session-id" = [guid]::NewGuid().ToString()}
$b2bPolicy 

Notice that there are two added random guids used here. These are required, and seems to be used for tracking Azure Portal issues and things like that.

Step 3 – Findout out what is behind “a button”

Self service password reset is also a thing that is not available through the Microsoft Graph. Here is how to determine what API endpoint is used for the below botton:

This is demoed using Chrome, but you can use the developer tool in your favorite browser, or fiddler.

  • Open developers tools (F12) and go to the network tab
  • Click “Preserve log”
  • Click F5 to refersh and you’ll get a bounch of results in your log.
  • Sort by type to find “xhr” types
  • Find a relevant API:
  • Copy the link address into a script like this
$sspr = Invoke-RestMethod 'https://main.iam.ad.ext.azure.com/api/PasswordReset/PasswordResetPolicies?getPasswordResetEnabledGroup=true' -Headers @{Authorization = "Bearer $($token.access_token)"; "x-ms-client-request-id" = [guid]::NewGuid().ToString(); "x-ms-client-session-id" = [guid]::NewGuid().ToString()}
$sspr

From this we’ll get the following output:

objectId                              : default
enablementType                        : 2
numberOfAuthenticationMethodsRequired : 2
emailOptionEnabled                    : True
mobilePhoneOptionEnabled              : True
officePhoneOptionEnabled              : False
securityQuestionsOptionEnabled        : False
mobileAppNotificationEnabled          : True
mobileAppCodeEnabled                  : True
numberOfQuestionsToRegister           : 5
numberOfQuestionsToReset              : 3
registrationRequiredOnSignIn          : True
registrationReconfirmIntevalInDays    : 180
skipRegistrationAllowed               : True
skipRegistrationMaxAllowedDays        : 7
customizeHelpdeskLink                 : False
customHelpdeskEmailOrUrl              :
notifyUsersOnPasswordReset            : True
notifyOnAdminPasswordReset            : False
passwordResetEnabledGroupIds          : {fed601c7-3d90-46db-8b4d-36bcdbe29f69}
passwordResetEnabledGroupName         : SSPRSecurityGroupUsers
securityQuestions                     : {}
registrationConditionalAccessPolicies : {}
emailOptionAllowed                    : True
mobilePhoneOptionAllowed              : True
officePhoneOptionAllowed              : True
securityQuestionsOptionAllowed        : True
mobileAppNotificationOptionAllowed    : True
mobileAppCodeOptionAllowed            : True

As you can see, PLENTY of information that can be consumed 🙂

Good luck!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s