Scott
Scott

Reputation: 61

Microsoft Graph API - Blazor Server App .NET 5.0 using Azure Authentication , MsalUiRequiredException was thrown due to a challenge for the user

About (help needed on the following issue)

The issue that I currently have at the moment is that when requesting a new bearer token within the same browser session. Sometimes I am able to retrieve the bearer token and pull data from Microsoft Graph API, while on other occasions receive the error message: -

The error intermittently happens on execute of this line of code: -

token = await TokenAcquisitionService.GetAccessTokenForUserAsync("User.Read").ConfigureAwait(false);

Causing a try catch error: -

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

Additional Information

Written using Blazor Server App .NET 5.0 using Microsoft Azure Authentication

Within my startup.cs class added the following: -

public void ConfigureServices(IServiceCollection services)
{
  services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
     .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
     .EnableTokenAcquisitionToCallDownstreamApi("User.Read") 
     .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
     .AddInMemoryTokenCaches();
}

Within my index.razor page: -

@using Microsoft.Extensions.Configuration;
@using Microsoft.Identity.Web
@inject IConfiguration Configuration
@inject Microsoft.Identity.Web.ITokenAcquisition TokenAcquisitionService
@inject MicrosoftIdentityConsentAndConditionalAccessHandler ConsentHandler

@page "/"
<p>Help!!!</p>

Within my index.razor.cs class: -

/// <summary>
/// The User constructor
/// </summary>
public User user { get; set; }

/// <summary>
/// Provides information about the current logged in user if any.
/// </summary>
[CascadingParameter]
public Task<AuthenticationState> authenticationStateTask { get; set; }

private GraphServiceClient GetGraphClient(string token)
        {
            return new GraphServiceClient(
                "https://graph.microsoft.com/beta", new DelegateAuthenticationProvider(async (request) =>
                {
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", token);
                await Task.FromResult<object>(null);
                }
            ));
        }

protected override async Task OnInitializedAsync()
{
   string token = null;
   try
   {
      var authenticationState = await authenticationStateTask;
      if (authenticationState.User.Identity.IsAuthenticated)
      {
         token = await TokenAcquisitionService.GetAccessTokenForUserAsync("User.Read").ConfigureAwait(false);
         GraphClient = Client.GetGraphClient(token);
         User = await graph.Me.Request().GetAsync();
      }
   }
   catch (Exception ex)
   {
      // This is the error I get, sometimes the above code executes OK and able to pull MS Graph user data, other times I get the error
      // {"IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent. "}

      Debug.WriteLine($"Token: {token}");
      ConsentHandler.HandleException(ex);
   }
}

Any help on this would be much appreciated!

Upvotes: 1

Views: 2199

Answers (1)

Scott
Scott

Reputation: 61

Managed to find the solution to my own problem myself, using the project located on the Microsoft web site Microsoft identity platform code samples (v2.0 endpoint) Look for Web applications --> Language/ Platform --> Blazor --> Call Microsoft Graph and click to download the project. else here is the direct link ms-identity-blazor-server

Within my startup.cs class added the following: -

public void ConfigureServices(IServiceCollection services)
{
string[] initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');

  wtSecurityTokenHandler.DefaultMapInboundClaims = false;
  services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
     .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
     .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) 
     .AddMicrosoftGraph(Configuration.GetSection("initialScopes"))
     .AddInMemoryTokenCaches();
}

Within my index.razor page: -

@page "/"

@using Microsoft.Identity.Web
@using Microsoft.Graph
@inject Microsoft.Graph.GraphServiceClient GraphServiceClient
@inject MicrosoftIdentityConsentAndConditionalAccessHandler ConsentHandler

@page "/"
<p>Help!!!</p>

Within my index.razor.cs class: -

/// The User constructor
public User user { get; set; }

private GraphServiceClient GraphClient { get; set; }

protected override async Task OnInitializedAsync()
{
  User = await GraphServiceClient.Me.Request().GetAsync();     
}

Within my appsettings.json

"DownstreamApi": {
    "BaseUrl": "https://graph.microsoft.com/beta",
    "Scopes": "User.Read"
  },

Upvotes: 2

Related Questions