I'm tring to instanciate a new instance of GraphServiceClient from Microsoft.Graph in the nugget manager.
What is already did:
Basicaly, here is the whole code from my ASP.NET Core 2.0 projet (Console Application) :
using Microsoft.Graph;
using Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace SendADUserListEmail.Services
{
// Response object from Azure AD
public class AzureADResponse
{
public string token_type { get; set; }
public int expires_in { get; set; }
public string access_token { get; set; }
}
/// <summary>
/// Micrososf Graph vs Azure AD Graph :
/// https://blogs.msdn.microsoft.com/aadgraphteam/2016/07/08/microsoft-graph-or-azure-ad-graph/
///
/// Introduction to the Azure Active Directory Graph API :
/// https://www.red-gate.com/simple-talk/cloud/security-and-compliance/azure-active-directory-part-5-graph-api/
///
/// ULTIMATE TUTORIAL ABOUT MICROSOFT GRAPH APIS
/// https://bytescout.com/blog/microsoft-graph-apis.html
///
/// Startup !!! TO READ !!! :
/// https://github.com/microsoftgraph/msgraph-sdk-dotnet
///
/// Creating the application Client ID and Client Secret from Microsoft Azure new portal
/// - Register an application on Azure Portal :
/// - 1. Accèder au portail
/// - 2. Inscription d'application
/// - 3. Voir Paramètres > Propriétés
/// https://www.netiq.com/communities/cool-solutions/creating-application-client-id-client-secret-microsoft-azure-new-portal/
///
/// Microsoft App Registration Portal (alternative method to register an app) :
/// https://apps.dev.microsoft.com
///
/// Microsoft Graph explorer (graph request tester) :
/// https://developer.microsoft.com/en-us/graph/graph-explorer
/// </summary>
class GraphApiHelper
{
// Client
GraphServiceClient GraphServiceClient = null;
// Tenant ID (directory ID)
private const string tenantId = "/*MY_TENANT_ID_FROM_AZURE_AD_PORTAL*/";
// App ID (client ID)
private const string appId = "/*MY_APP_ID_FROM_AZURE_AD_PORTAL*/";
// Secret ID (app password)
private const string appSecret = "/*MY_APP_SECRET_FROM_AZURE_AD_PORTAL*/";
public void Connexion()
{
string url = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
string @params = $"client_id={appId}&" +
"scope=User.Read&" +
$"client_secret={appSecret}&" +
"grant_type=client_credentials";
try
{
string accessToken = "";
string jsonStringResult = "";
AzureADResponse response = new AzureADResponse();
// Getting the access token from Azure AD
using (WebClient webClient = new WebClient())
{
webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
jsonStringResult = webClient.UploadString(url, @params);
response = JsonConvert.DeserializeObject<AzureADResponse>(jsonStringResult);
// Set the access token
accessToken = response.access_token;
}
// Initialize the Microsoft Graph client
GraphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}));
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public List<SystemUser> GetSystemUserList()
{
Connexion();
return null;
}
}
}
I'm geting this error while trying to execute the post request with System.Net.WebClient :
string url = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
string @params = $"client_id={appId}&" +
"scope=User.Read&" +
$"client_secret={appSecret}&" +
"grant_type=client_credentials";
jsonStringResult = webClient.UploadString(url, @params);
The remote server returned an error: (400) Bad Request.
Based on this source: https://learn.microsoft.com/en-us/graph/auth-v2-service I'm suppose to receive something like this:
{
"token_type": "Bearer",
"expires_in": 3599,
"access_token":
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
What I need is the access token to initialize GraphServiceClient.
Any idea on why Microsoft Azure failed on this request?
You should follow juunas advice and use a library like ADAL which does that for you.
If you want to do the call to retrieve the token yourself, first verify that the problem comes from your code and not from your application registration by testing the same request from a tool like Postman. As you receive an error 400 it's probably that it's fro your code and that your request is not well formed.
I am not used to make http calls with a WebClient so I don't know what's wrong but I would have say it might be linked to the way you are handling your params. If I were you I would have used and HttpClient, you can find some samples of queries with form url encoded in stackoverflow (How to POST using HTTPclient content type = application/x-www-form-urlencoded).