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();
}