Vinay Vinay
Vinay Vinay

Reputation: 1

Graph API - Getting "The remote server returned an error: (400) Bad Request."Error while request AccessToken using multiTenant

Actually I'm trying to get Access Token using Using the TenantId after Admin consent successfully completed admin by using the following endpoint

https://login.microsoftonline.com/common/adminconsent

then I am requesting the AccessToken Endpoint Using Tenant ID

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

by using HttpWebRequest by passing all the required fields

tenant : 6292ef34-37a8-4687-b8b3-7dd8d54a8a42

Code for API call using HttpWebRequest

public static string AdminConsentAccessToken(string tenant, string state = "", string admin_concent = "")
{
    string postData="{\"client_id\":\"65577dd2-cc76-46af-a1ac-71582eac6af2\",\"scope\":\"https://graph.microsoft.com/.default",\"client_secret\":\"my_client_secret\","\grant_type\":"\client_credentials\"}"
    string result = string.Empty;
    try
    {
        var httpRequest = (HttpWebRequest)WebRequest.Create($"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token");
        httpRequest.Method = "POST"; ;
        httpRequest.Accept = "application/json";
        httpRequest.ContentType = "application/x-www-form-urlencoded";
    
        using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
        {
            streamWriter.Write(postData);
        }
        var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            result = streamReader.ReadToEnd();
        }
    }
    catch (Exception ex)
    {
    //exception
    }
    return result;
}

With this code I am getting following error : "The remote server returned an error: (400) Bad Request." and status : Protocol Error, can you please check code suggest what went wrong.

and I have tried this from post man also the i am getting 400 - Bad Request (The request cannot be fulfilled due to bad syntax.)

POST : https://login.microsoftonline.com/6292ef34-37a8-4687-b8b3-7dd8d54a8a42/oauth2/v2.0/token
Header : Content-Type : application/x-www-form-urlencoded
Body :
{
"grant_type": "client_credentials",
"client_id":"65577dd2-cc76-46af-a1ac-71582eac6af2",
"scope":"https://graph.microsoft.com/.default",
"client_secret": "my_client_secret"
}

Response :
{
"error": "invalid_request",
"error_description": "AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: 68beea44-7863-4e08-97c9-526ada9d0300\r\nCorrelation ID: 064a85fe-6d37-43bd-ae59-3dca04232188\r\nTimestamp: 2022-06-24 09:08:56Z",
"error_codes": [
900144
],
"timestamp": "2022-06-24 09:08:56Z",
"trace_id": "68beea44-7863-4e08-97c9-526ada9d0300",
"correlation_id": "064a85fe-6d37-43bd-ae59-3dca04232188",
"error_uri": "https://login.microsoftonline.com/error?code=900144"
}

Upvotes: 0

Views: 2756

Answers (4)

Tiny Wang
Tiny Wang

Reputation: 16066

I can get access token by your request

enter image description here

But this doesn't mean you can get access token by simulating a post request in your code, Microsoft require users to use Msal library to authenticate and get access token. For example, with client credential flow to get access token:

using Azure.Identity;

var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "your_azuread_clientid";
var clientSecret = "corresponding_client_secret";
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret);
var tokenRequestContext = new TokenRequestContext(scopes);
var token = clientSecretCredential.GetTokenAsync(tokenRequestContext).Result.Token;

enter image description here

If you used msal sdk to authenticate your app, you can also use graph sdk to call graph api:

using Azure.Identity;
using Microsoft.Graph;

var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "hanxia.onmicrosoft.com";
var clientId = "azure_ad_app_id";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var temp = await graphClient.Users.Request().GetAsync();

Upvotes: 1

fatih
fatih

Reputation: 229

You create a request model:

public class ReqModel
{
    public string client_id{ get; set; }
    public string  scope{ get; set; }
    public string  client_secret{ get; set; }
    public string grant_type{ get; set; }
}

Then you try to create postData like this:

    ReqModel reqModel = new()
        {
            client_id = "65577dd2-cc76-46af-a1ac-71582eac6af2",
            scope = "https://graph.microsoft.com/.default",
            client_secret = "my_client_secret",
            grant_type = "client_credentials"
        };


        string postData = JsonConvert.SerializeObject(reqModel, Newtonsoft.Json.Formatting.Indented);

Upvotes: 0

user2250152
user2250152

Reputation: 20823

In the Postman ensure that checkbox x-www-urlencoded is selected on tab Body.

Looks like you are sending data in json format.

enter image description here

Upvotes: 0

Mickaël Derriey
Mickaël Derriey

Reputation: 13714

Try using application/json for the Content-Type header of your request instead of application/x-www-form-urlencoded.

Upvotes: 0

Related Questions