timtos
timtos

Reputation: 2305

Access GraphAPI from within a WebAPI project (via Microsoft.Identity.Web)

I am trying to make a simple call with the Microsoft Graph API SDK using the Microsoft.Identity.Web library from within a web api project.

The user is already logged in and is calling protected controllers from a SPA and everything is working fine - but now, these controlles should make a call to the Graph API and I don't get it up and running...

I found a perfect sample that shows how easy it is with a wep app here. And it is really as easy as this:

.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
   .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
   .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
   .AddInMemoryTokenCaches();

As I want to use this functionality within a web api project, I created a new project of that type, copied the code and got:

MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.

and

MicrosoftIdentityWebChallengeUserException: IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent.

Then I thought, ok, as this is now api related, I will change the code from

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                 .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                 .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "user.read" })
                 .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
                 .AddInMemoryTokenCaches();

to

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                 .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"))
                 .EnableTokenAcquisitionToCallDownstreamApi()
                 .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
                 .AddInMemoryTokenCaches();

but I get the same error.

I navigated to https://aka.ms/ms-id-web/ca_incremental-consent as mentioned in the exception message and found Handling incremental consent or conditional access in web APIs:

public async Task<string> CallGraphApiOnBehalfOfUser()
{
 string[] scopes = { "user.read" };

 // we use MSAL.NET to get a token to call the API On Behalf Of the current user
 try
 {
  string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes);
  dynamic me = await CallGraphApiOnBehalfOfUser(accessToken);
  return me.UserPrincipalName;
 }
 catch (MicrosoftIdentityWebChallengeUserException ex)
 {
  await _tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeaderAsync(scopes, ex.MsalUiRequiredException);
  return string.Empty;
 }
 catch (MsalUiRequiredException ex)
 {
  await _tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeaderAsync(scopes, ex);
  return string.Empty;
 }
}

I tried this and get the same error:

IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent.

When later finding the sample Web API calling downstream web API, I thought now everything gets easy but although, a WebAPI is calling Microsoft Graph, they are using a Windows application to sign in the user first.

On stackoverflow, I found How to access Graph API from Web API in SPA application but unfortunately, this question is hopefully out-dated.

Has anyone an idea how to get the sample code for the web app up and running in a web api only project? (No windows application involved)

I am using

Microsoft.Graph 3.21.0

Microsoft.Identity.Web version 1.4.0

Upvotes: 3

Views: 3354

Answers (2)

Stef Heyenrath
Stef Heyenrath

Reputation: 9830

I think that instead of using AddMicrosoftGraph, you need to use AddMicrosoftGraphAppOnly.

So in your example this will be like:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddMicrosoftGraphAppOnly(authenticationProvider => new GraphServiceClient(authenticationProvider))
    .AddInMemoryTokenCaches();

Upvotes: 5

AlfredoRevilla-MSFT
AlfredoRevilla-MSFT

Reputation: 3495

2. Web API now calls Microsoft Graph is that one that you're looking for. The fact that the client is a windows application is not relevant. Try it and let me know how it goes.

Upvotes: 0

Related Questions