Menu Home

Get Azure AD domains from TenantID

In Azure AD a tenant is uniquely identified by a tenant ID which is a guid. Unfortunately guids are not very user friendly, so most users remembers their AD tenants by the domain name, it could e.g. be
sjkp.onmicrosoft.com.

If you are working with the Azure management api, you can get a list of all tenants a given user have access to from the following endpoint:
https://management.azure.com/tenants?api-version=2014-04-01
Unfortunately that response looks like this

{
    "value": [
        {
            "id": "/tenants/f386bf36-faf3-4000-adec-1f6d78dbf0bf",
            "tenantId": "f386bf36-faf3-4000-adec-1f6d78dbf0bf"
        },
        {
            "id": "/tenants/c47429d7-cdd7-456b-bfcc-003ebd418b05",
            "tenantId": "c47429d7-cdd7-456b-bfcc-003ebd418b05"
        },
        {
            "id": "/tenants/14e88547-8862-4887-95f3-839be792d384",
            "tenantId": "14e88547-8862-4887-95f3-839be792d384"
        },
        {
            "id": "/tenants/37597dd5-5816-4d7a-99e8-b2e6c3f4d0c2",
            "tenantId": "37597dd5-5816-4d7a-99e8-b2e6c3f4d0c2"
        }        
    ]
}

Not something that you can present to a user and expect them to know which tenant are which. Luckily there’s another endpoint that can help us provide some extra details about the Azure AD instance behind the tenant id.

The endpoint that can help us out are part of the azure ad graph API and located at
https://graph.windows.net/[tenantId]/tenantDetails?api-version=1.6
Note that tenantDetails are case sensitive in this api.

A get request to the above endpoint with a valid access token returns the following, from which you can dig out the tenant’s domain names from the verifiedDomains array. In the example it is xxxxhotmail.onmicrosoft.com (obviously I anonymized it)

{
    "odata.metadata": "https://graph.windows.net/f386bf36-faf3-4000-adec-1f6d78dbf0bf/$metadata#directoryObjects/Microsoft.DirectoryServices.TenantDetail",
    "value": [{
        "odata.type": "Microsoft.DirectoryServices.TenantDetail",
        "objectType": "Company",
        "objectId": "f386bf36-faf3-4000-adec-1f6d78dbf0bf",
        "deletionTimestamp": null,
        "assignedPlans": [{
            "assignedTimestamp": "2015-08-07T01:40:28Z",
            "capabilityStatus": "Enabled",
            "service": "WindowsAzure",
            "servicePlanId": "fca3e605-0754-4279-8504-3f1229f29614"
        }, {
            "assignedTimestamp": "2013-12-24T11:11:56Z",
            "capabilityStatus": "Enabled",
            "service": "AccessControlServiceKey",
            "servicePlanId": "e4f8ab60-7072-4bb1-a183-08024ca10c54"
        }, {
            "assignedTimestamp": "2013-10-14T03:34:46Z",
            "capabilityStatus": "Enabled",
            "service": "AccessControlServiceS2S",
            "servicePlanId": "11d043ce-3f21-4ff8-8a7f-ac68e2decc5b"
        }, {
            "assignedTimestamp": "2013-10-14T03:34:46Z",
            "capabilityStatus": "Enabled",
            "service": "AccessControlServiceS2S",
            "servicePlanId": "11d043ce-3f21-4ff8-8a7f-ac68e2decc5b"
        }, {
            "assignedTimestamp": "2013-10-14T03:34:46Z",
            "capabilityStatus": "Enabled",
            "service": "AccessControlServiceS2S",
            "servicePlanId": "11d043ce-3f21-4ff8-8a7f-ac68e2decc5b"
        }],
        "city": null,
        "companyLastDirSyncTime": null,
        "country": null,
        "countryLetterCode": "DK",
        "dirSyncEnabled": null,
        "displayName": "Simtex",
        "marketingNotificationEmails": [],
        "postalCode": null,
        "preferredLanguage": "en",
        "provisionedPlans": [{
            "capabilityStatus": "Enabled",
            "provisioningStatus": "Success",
            "service": "AccessControlServiceS2S"
        }, {
            "capabilityStatus": "Enabled",
            "provisioningStatus": "Success",
            "service": "AccessControlServiceS2S"
        }],
        "provisioningErrors": [],
        "securityComplianceNotificationMails": [],
        "securityComplianceNotificationPhones": [],
        "state": null,
        "street": null,
        "technicalNotificationMails": ["xxxx@hotmail.com"],
        "telephoneNumber": null,
        "verifiedDomains": [{
            "capabilities": "Email, OfficeCommunicationsOnline",
            "default": true,
            "id": "00050000802C9A98",
            "initial": true,
            "name": "xxxxhotmail.onmicrosoft.com",
            "type": "Managed"
        }]
    }]
}

Categories: Windows Azure

Tagged as:

Simon J.K. Pedersen

1 reply

  1. Thank you for this article. I am trying to provide a guided experience for connecting our application to Azure subscriptions by giving choices for “other directories” they have access to. However, I am unable to access any information on these “other tenants” that are listed by the Azure management API.

    I can not get tenantDetails for any tenant other than the access tenant (from JWT identity). Can you see what I am doing wrong?

    These all fail when ‘accessTenant’ does not match ‘otherTenant’:

    1. user+App Graph access {otherTenant}/tenantDetails
    fails with “Invalid domain name in the request url.”

    2. user+App Graph access {accessTenant}/tenantDetails/{otherTenant}
    fails with “Invalid tenant identifier; it must match that of the requested tenant.”

    3. app Graph access {otherTenant}/tenantDetails
    fails with “insufficient privileges” (tenantId/oauth2/token)
    or “The identity of the calling application could not be established.” (common/oauth2/token)

    Any help would be greatly apreciated. It is driving me nuts. Maybe some trick when getting access token? I am using common/oauth to get user+App access token to avoid prompting for directory name.

Leave a Reply

Your email address will not be published. Required fields are marked *