Home > other >  Azure AD - Using Graph API access token from Angular SPA in C# Web API
Azure AD - Using Graph API access token from Angular SPA in C# Web API

Time:09-30

It looks like I'm missing something fundamental when it comes to Azure AD Enterprise applications.
I have an application running as Angular SPA with a backend ASPNETCore API that have 2 separate App Registrations in Azure AD. MyAPI is exposed as a scope "access_as_user" in MySPA.
MyAPI has no authentication flow on it's own.

I want to implement delegated access MS Graph API calls through MyAPI. Currently it only runs as a daemon service with Application permissions.

MySPA can call https://graph.microsoft.com/v1.0/me/ without any issues and profile is returned.
I can see that the jwt has User.Read scope:

"scp": "openid profile User.Read email"

MyAPI fails the same request with the following error:

code: "InvalidAuthenticationToken"
message: "Access token validation failure. Invalid audience."
public async Task<IActionResult> GetProfile([FromHeader] string authorization)
{
   var tokenFromHeader = authorization.Replace("Bearer ", "");
   return await ("https://graph.microsoft.com/v1.0/me/")
      .WithOAuthBearerToken(tokenFromHeader)
      .WithHeader("Content-Type", "application/json")
      .GetJsonAsync();
    }

The JWT naturally has the scoped permission, so the audience error makes sense

"aud": "api://XXXXXXXXXXXXXXXXXXXXXXXX",
"scp": "access_as_user"

How can MyAPI access MS Graph API on behalf of users ?

CodePudding user response:

Managed to solve this with Graph SDK

I added the following in my startup after .AddMicrosoftIdentityWebApi(Configuration)

.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph()
.AddInMemoryTokenCaches();

This allowed me to inject the service client in my API controller:

public GraphAPIController(GraphServiceClient client)
{
   this.client = client;
}

public async Task<IActionResult> GetProfile()
{
   return await client.Me.Request().GetAsync();
}
  • Related