0
votes

The below code is perfectly working fine and returning needed access token from azure but if I am trying to execute same function from node js or postman with it is prompting an error as:

{"error":"invalid_client","error_description":"AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided.\r\nTrace ID: 922f61ca-0349-47fc-8c60-326cb29b2000\r\nCorrelation ID: 3d39e54d-deb2-49de-84c0-9705e2977c2e\r\nTimestamp: 2017-07-18 14:29:14Z","error_codes":[70002,50012],"timestamp":"2017-07-18 14:29:14Z","trace_id":"922f61ca-0349-47fc-8c60-326cb29b2000","correlation_id":"3d39e54d-deb2-49de-84c0-9705e2977c2e"}

But same working very well with any number of times in java environment

 HttpPost httpPost = new HttpPost("https://login.microsoftonline.com/" + environment.getTenantId() + "/oauth2/token");
 List<NameValuePair> nameValuePairs = new ArrayList(3);
 nameValuePairs.add(new BasicNameValuePair("grant_type", "client_credentials"));
 nameValuePairs.add(new BasicNameValuePair("client_id", environment.getClientId()));
 nameValuePairs.add(new BasicNameValuePair("client_secret", environment.getClientSecret()));
 nameValuePairs.add(new BasicNameValuePair("resource", "https://graph.windows.net"));
 httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
 httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
 HttpResponse response = httpClient.execute(httpPost);
 String postResponse = EntityUtils.toString(response.getEntity());
 String startPoint = "\"access_token\":\"";
 int startIndex = postResponse.indexOf(startPoint);
 int adjustPoint = startIndex + startPoint.length();
 String objectId = postResponse.substring(adjustPoint);
 int tokenLength = objectId.length();
 String accessToken = objectId.substring(0, tokenLength - 2);
 return accessToken;
1
Found the solution, I was sending the options from body but it should be from FormData.shaik

1 Answers

0
votes

For me the HttpClient APIs always work well. I think the class you are using does not encode the values correctly.

// Static field within class to share the same client instance
private static HttpClient Client = new HttpClient();

public async Task<string> GetAccessTokenAsync()
{
    //Get the environment variable from somewhere

    var request = new HttpRequestMessage(HttpMethod.Post, "https://login.microsoftonline.com/" + environment.getTenantId() + "/oauth2/token");

    var keyValues = new List<KeyValuePair<string, string>>();
    keyValues.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
    keyValues.Add(new KeyValuePair<string, string>("client_id", environment.getClientId()));
    keyValues.Add(new KeyValuePair<string, string>("client_secret", environment.getClientSecret()));
    keyValues.Add(new KeyValuePair<string, string>("resource", "https://graph.windows.net"));

    request.Content = new FormUrlEncodedContent(keyValues);

    HttpResponseMessage response = await Client.SendAsync(request);

    string json = await response.Content.ReadAsStringAsync();

    JObject tokenResponse = JObject.Parse(json);

    string accessToken = tokenResponse["access_token"];
    return accessToken;
}