Unauthorized when try to get token using ARM API

2019-07-30 20:57发布

问题:

I am trying to get token from using Azure Resource Manager API but getting 401-Unauthorized in response.I have my code as below :

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
   "Basic",
   Convert.ToBase64String(
       System.Text.ASCIIEncoding.ASCII.GetBytes(
           string.Format("{0}:{1}", client_Id, client_secret))));

var content = new FormUrlEncodedContent(new KeyValuePair<string, string>[]{

            new KeyValuePair<string, string>("grant_type", "client_credentials")
        });

content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

var response = client.PostAsync("https://login.windows.net/subscriptionId/oauth2/token", content);

回答1:

According to your code, you could refer to the following code to retrieve your token:

var client = new HttpClient();

var content = new FormUrlEncodedContent(new KeyValuePair<string, string>[]{
    new KeyValuePair<string, string>("resource", "https://management.core.windows.net/"),
    new KeyValuePair<string, string>("grant_type", "client_credentials"),
    new KeyValuePair<string, string>("client_id", "{ClientID}"),
    new KeyValuePair<string, string>("client_secret", "{ClientSecret}")
});

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PostAsync("https://login.windows.net/{TennantID}/oauth2/token", content);

Console.WriteLine(await response.Content.ReadAsStringAsync());

Result:

For more details, you could refer to this blog about using the Azure ARM REST API – Get Access Token.



回答2:

I dont fully understand your code but i know how to construct ARM API calls so i can help you out with the core facts. What jumps out at me is the fact that your POST URL looks wrong:

  1. you should be using https://login.microsoftonline.com/ - check out the following blogpost Simplifying our Azure AD Authentication Flows

  2. There needs to be the tenantID in your POST uri, not the subscriptionID. Access to subscriptions is managed through assigning RBAC Roles to the serivceprincipal created for the AzureAD App

Here is an example call. I use Postman to check if my constructed calls use the correct values and parameters:

Request

POST /[YOURTENANTID]/oauth2/token?api-version=1.0 HTTP/1.1
Host: login.microsoftonline.com
Cache-Control: no-cache
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
Postman-Token: [token]

grant_type=client_credentials&client_id=[YOURCLIENTID]&client_secret=[YOUR-URLENCODED-Secret]&resource=https://management.azure.com/

response:

{
 "token_type": "Bearer",
 "expires_in": "3599",
 "ext_expires_in": "0",
 "expires_on": "1485695000",
 "not_before": "1485691100",
 "resource": "https://management.azure.com/",
 "access_token": "[TOKEN]"
}