Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access token validation failure Microsoft Graph API

I am building a console application in C#.
I want to make some calls to Microsoft Graph API to access and edit some Excel files in my SharePoint so I can automate some processes in my Organization.


The logic of the app is simple.

  1. I call Azure Active Directory to authenticate this console application using the clients credential flow which means we will provide a clientsID and AppKey. I took the clientsID and AppKey from Azure Active Directory > App Registrations. enter image description here
  2. Then I want to receive the access token and use this to make a GET Request to the Microsoft Graph API.
    E.g https://graph.microsoft.com/v1.0/me/

    But then response I get is this:

{
  "error": {
    "code": "InvalidAuthenticationToken",
    "message": "Access token validation failure. Invalid audience.",
    "innerError": {
      "request-id": "0a3ec**************",
      "date": "2019-10-15T13:54:33"
    }
  }
}

Below you will find the full code of my application with the two methods of getting the access token and calling the Graph API:

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IdentityModel.Tokens;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using AuthenticationContext = Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext;

namespace Project_Budget
{
    class Program
    {
        private const string clientId = "14f1****************";
        private const string aadInstance = "https://login.microsoftonline.com/{0}";
        private const string tenant = "******.onmicrosoft.com";
        private const string resource = "https://graph.windows.net";
        private const string appKey = "IKV***********";
        static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

        private static HttpClient httpClient = new HttpClient();
        private static AuthenticationContext context = null;
        private static ClientCredential credential = null;

        static void Main(string[] args)
        {
            context = new AuthenticationContext(authority);
            credential = new ClientCredential(clientId,appKey);

            Task<string> token = GetToken();
            token.Wait();
            //Console.WriteLine(token.Result + "\n");

            Task<string> graphCall = GetExcelFile(token.Result);
            graphCall.Wait();
            Console.WriteLine(graphCall.Result + "\n");
            Console.ReadLine();

        }

        private static async Task<string> GetExcelFile(string result)
        {
            string apiJsonResult = null;
            
            var apiCallString = "https://graph.microsoft.com/v1.0/me/";
         
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result);
            var getResult = await httpClient.GetAsync(apiCallString);

            if (getResult.Content != null)
            {
                apiJsonResult = await getResult.Content.ReadAsStringAsync();
            }

            
            return apiJsonResult;
        }

        private static async Task<string> GetToken() 
        {
            AuthenticationResult result = null;
            string token = null;
            result = await context.AcquireTokenAsync(resource, credential); //authentication context object
            token = result.AccessToken;
            return token;
        }

        
    }
}

I have given all the access required for the app to run. Also I run the query on Graph Explorer and runs properly.
enter image description here Why do I get this error on the console application?

like image 639
John Sp Avatar asked Oct 15 '19 14:10

John Sp


Video Answer


1 Answers

Ideally, the resource should actually be

private const string resource = "https://graph.microsoft.com";

But you still need to select the scopes that you want to target in your application. The way you are doing it at the moment does seem to acquire/set the relevant scopes which is done for you by Graph Explorer.

I would suggest following this quick start tutorial on how to build a dot net core console app and you should be up and running in no time. It uses the MSAL library which works better than the ADAL library you are using in your scenario.

https://docs.microsoft.com/en-us/graph/tutorials/dotnet-core

like image 96
Eastman Avatar answered Oct 23 '22 04:10

Eastman