From Domain to TenantID

Ha, I discovered that I kind of like to write short posts Smile so here there’s another one.

Azure AD endpoints can be constructed with both domain and tenantID interchangeably, “https://login.windows.net/developertenant.onmicrosoft.com/oauth2/authorize” and “https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/oauth2/authorize” are functionally equivalent – however the tenantID has some clear advantages. For example: it is immutable, globally unique and non-reassignable, while domains do indeed change hands on occasions. Moreover, you can have many domains associated to a tenant but only one tenantID. Really, the only thing that the domain has going for itself is that it is human readable and there’s a reasonable chance a user can remember and type it.

Per the above, there are times in which it can come in useful to find out the TenantID for a given domain. The trick is reeeeeally simple. You can use the domain to construct one of the AAD endpoints which return tenant metadata, for example the OpenId Connect one; such metadata will contain the tenantID. In practice: say that you know that the target domain is developertenant.onmicrosoft.com. How do I find out the corresponding tenantID, without even being authenticated?

Easy. I do a GET of https://login.windows.net/developertenant.onmicrosoft.com/.well-known/openid-configuration.

The result is a JSON file that has the tenantID all over it:

{
   "authorization_endpoint" : "https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/oauth2/authorize",
   "check_session_iframe" : "https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/oauth2/checksession",
   "end_session_endpoint" : "https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/oauth2/logout",
   "id_token_signing_alg_values_supported" : [ "RS256" ],
   "issuer" : "https://sts.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/",
   "jwks_uri" : "https://login.windows.net/common/discovery/keys",
   "microsoft_multi_refresh_token" : true,
   "response_modes_supported" : [ "query", "fragment", "form_post" ],
   "response_types_supported" : [ "code", "id_token", "code id_token", "token" ],
   "scopes_supported" : [ "openid" ],
   "subject_types_supported" : [ "pairwise" ],
   "token_endpoint" : "https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/oauth2/token",
   "token_endpoint_auth_methods_supported" : [ "client_secret_post", "private_key_jwt" ],
   "userinfo_endpoint" : "https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/openid/userinfo"
}

Whip out your favorite JSON parsing class, and you’re done. Ta—dahh ♫

Leave a Reply

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