From Domain to TenantID
Ha, I discovered that I kind of like to write short posts 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 ♫