Scenario - Frontend will login to microsoft and will give access token to backend, with that token I am unable to create microsoft graph api instance.
I am trying to access the user data using microsoft graph api and I receive this error.
Status Code: Unauthorized
Microsoft.Graph.ServiceException: Code: InvalidAuthenticationToken
Message: Access token validation failure. Invalid audience.
Inner error:
AdditionalData:
date: 2020-09-30T11:00:43
request-id: -8561--aebc-ff72e69942c4
client-request-id: -8561-4fb2-aebc-
ClientRequestId: c4f169bb-8561-4fb2-aebc-
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.UserRequest.GetAsync(CancellationToken cancellationToken)
at OptimusPortal.Controllers.WeatherForecastController.GetAsync() in C:\Users\bippan.kumar\Documents\GitHub\OIC\OptimusPortal\OptimusPortal\Controllers\WeatherForecastController.cs:line 52
at lambda_method(Closure , Object )
at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
My ConfigureServices function in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
string token;
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.SaveToken = true;
options.Events = new JwtBearerEvents
{
OnTokenValidated = OnTokenValidated
};
options.Authority += "/v2.0";
options.Audience = "api://xyz";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
//I have kept these settings in place to provide easy support for docker.
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers();
}
Function where I am creating GraphServiceClient instance. Error is thrown at last line of code in this function.
[HttpGet]
public async Task<IEnumerable<WeatherForecast>> GetAsync()
{
var token = await HttpContext.GetTokenAsync("access_token");
GraphServiceClient graphServiceClient =
new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
{
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token);
})
);
// Make a Microsoft Graph API query
// Error is thrown at this line of code
var users = await graphServiceClient.Me.Request().GetAsync();
}
It sounds like you are trying to access the Graph API on behalf of a user. Keep in mind there is also a way to access without a user using a different workflow. Remember you need to register the app with Entra ID (previously Azure AD). Then you need to configure Graph client for user authentication:
Program.cs
https://learn.microsoft.com/en-us/graph/tutorials/dotnet?tabs=aad&tutorial-step=3