0

To continue my quest to programmatically create and Azure application (this continues from https://stackoverflow.com/a/44753728/1332416), I have core that acquires a subscriptionID and a tenantId as follows, but I'm at loss as how could I create an application and its associated service principal locally. This is basically where New-AzureRmADApplication and New-AzureRmADServicePrincipal would be used in case of PowerShell. This question is partially answered at https://stackoverflow.com/a/44631758/1332416, but it looks like .NET Core may be the cause of some problems here as the types aren't to be found.

To be more concrete, I have code as follows to

string resource = "https://management.core.windows.net/";
string clientId = "1950a258-227b-4e31-a9cf-717495945fc2";
string userName = "<replace>";
string password = "<replace>";
string apiVersion = "2016-06-01";

using(var client = new HttpClient())
{
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    string tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/token";
    var body = $"resource={resource}&client_id={clientId}&grant_type=password&username={userName}&password={password}";
    var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
    var response = await client.PostAsync(tokenEndpoint, stringContent).ConfigureAwait(false);
    var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

    JObject jobject = JObject.Parse(result);
    var token = jobject["access_token"].Value<string>();

    client.DefaultRequestHeaders.Add("Authorization", $"bearer {token}");
    var subcriptions = await client.GetStringAsync($"https://management.azure.com/subscriptions?api-version={apiVersion}").ConfigureAwait(false);
    var tenants = await client.GetStringAsync($"https://management.azure.com/tenants?api-version={apiVersion}").ConfigureAwait(false);
    Console.WriteLine(subcriptions);
    Console.WriteLine(tenants);

    //We have the SubscriptionID, TenantId and the token to
    //the subscription here. How to do New-AzureRmADApplication and New-AzureRmADServicePrincipal with the application ID here? Specifically I'm considering to use a certificate thumbrint if it matters.
    //var subscription = "... from subscriptions...";
    //var tenantId = "... from tenants...";
}
Veksi
  • 3,556
  • 3
  • 30
  • 69

1 Answers1

2

You can acquire an access token and call Azure AD Graph API to create the application and service principal. (Microsoft Graph API also allows it, though only through the beta endpoint)

You can find the application entity documentation here: https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/entity-and-complex-type-reference#application-entity

To acquire the token, your app will need to have the necessary delegated/app permissions granted in Azure AD for Azure AD Graph API.

Then when you get the token, use https://graph.windows.net as the resource.

Then you should be able to POST to https://graph.windows.net/tenant-id/applications?api-version=1.6 with a body like this:

{
  "displayName":"Test app",
  "identifierUris": [
    "https://mytenant.onmicrosoft.com/testapp"
  ],
  "homePage":"http://localhost"
}

Replace tenant-id in the URL with your tenant id.

That's the application created, in the response you will get the created app.

Grab the appId field from it, you will need it to create the service principal.

Then make a POST to: https://graph.windows.net/tenant-id/servicePrincipals?api-version=1.6 with a body like this:

{
  "appId":"eb167a6d-aaaa-aaaa-aaaa-46e981be37fa"
}

And that should create the corresponding service principal.

juunas
  • 54,244
  • 13
  • 113
  • 149
  • Microsoft seem to recommend using the newer Graph API, see https://msdn.microsoft.com/en-us/library/azure/ad/graph/howto/azure-ad-graph-api-operations-overview for instance. Let me examine this a bit... – Veksi Jul 03 '17 at 20:11
  • Yes :) But the specific functionality is still only on the beta endpoint of MS Graph. If you are willing to use that, you can achieve same using it. – juunas Jul 03 '17 at 20:12
  • As you probably know, it's near midnight already. I have practically zero knowledge of these APIs, so I have to postpone experimenting till tomorrow. But I think the beta is the way to go, I'm a bit worried how it turns out with the code I have already (barely) functioning (see the code) and .NET Core, so experimenting a bit and see if I should update the question (maybe I should replace `azure-graph-api`. – Veksi Jul 03 '17 at 20:47
  • A little while, it appears the same access token as I use in the code snippet I have already doesn't work with this API (I get access denied back). I think I need to check the log-in phase still. – Veksi Jul 05 '17 at 20:43
  • You need a different token for the graph API. Request another one, but set the resource as `https://graph.microsoft.com`. – juunas Jul 05 '17 at 21:03
  • Better late than never. I went off-grid (holiday) for a while. I didn't find a way to use the new, shiny Microsoft Graph API, but maybe that's a separate questions. As is deleting the created application (without going to Azure Portal to look for some information first). – Veksi Jul 16 '17 at 13:38