azure-ad-b2cazure-ad-msaladalazure-sdk-.netazure-oauth

How to acquire Azure management token and call HTTP in .NET for Azure B2C domain name availability check?


I've been working on setting up Azure AD B2C tenants and encountered a roadblock when trying to verify domain name availability before creating a tenant. Following a helpful response on my previous question, I learned about using Azure management API to check domain name availability and successfully obtained an access token via Azure CLI command:

az account get-access-token --resource=https://management.azure.com --query accessToken --output tsv

I'm looking to implement this solution in a .NET application to programmatically acquire access token and make HTTP calls to check domain name availability.

Could someone provide guidance or a code snippet on programmatically acquiring access token in a .NET application and making HTTP POST request to Azure management API endpoint to check domain name availability?


Solution

  • Initially, register one Entra ID application and create client secret in it like this:

    enter image description here

    You can make use of below sample code to acquire Azure Management token and call API to check domain availability:

    using System;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Identity.Client;
    using Newtonsoft.Json.Linq;
    
    namespace AzureB2CDomainCheck
    {
        class Program
        {
            private static string clientId = "appId";
            private static string clientSecret = "secret";
            private static string tenantId = "tenantId";
            private static string authority = $"https://login.microsoftonline.com/{tenantId}";
            private static string subscriptionId = "subId";
            private static string apiVersion = "2021-04-01";
    
            static async Task Main(string[] args)
            {
                var accessToken = await GetAccessToken();
                await CheckDomainAvailability(accessToken);
            }
    
            private static async Task<string> GetAccessToken()
            {
                IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(clientId)
                    .WithClientSecret(clientSecret)
                    .WithAuthority(new Uri(authority))
                    .Build();
    
                AuthenticationResult result = await app.AcquireTokenForClient(new string[] { "https://management.azure.com/.default" })
                    .ExecuteAsync();
    
                return result.AccessToken;
            }
    
            private static async Task CheckDomainAvailability(string accessToken)
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    string requestUri = $"https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.AzureActiveDirectory/checkNameAvailability?api-version={apiVersion}";
    
                    string requestBody = @"{
                        ""name"": ""sridemob2c.onmicrosoft.com"",
                        ""countryCode"": ""US""
                    }";
    
                    HttpResponseMessage response = await httpClient.PostAsync(requestUri, new StringContent(requestBody, Encoding.UTF8, "application/json"));
    
                    if (response.IsSuccessStatusCode)
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();
                        JObject jsonResponse = JObject.Parse(responseContent);
                        bool isAvailable = jsonResponse["nameAvailable"].Value<bool>();
                        Console.WriteLine($"Domain name is {(isAvailable ? "available" : "not available")}");
                    }
                    else
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();
                        Console.WriteLine($"Error: {response.StatusCode}");
                        Console.WriteLine($"Response: {responseContent}");
                    }
                }
            }
        }
    }
    

    Response when domain available:

    enter image description here

    Response when domain not available:

    enter image description here

    Make sure to assign proper RBAC role to the service principal under subscription level.