ExecuteAsync doesn't return control to the debugger

Viewed 908

I'm trying to acquire a token using MSAL.NET and am pretty much using their tutorial code out of the box.

using Microsoft.Identity.Client;
using MyApp.Interfaces;
using System;
using System.Threading.Tasks;

namespace MyApp.NetworkServices
{
    public class MyAuthorizationClient : IMyAuthorizationClient
    {
        private readonly string[] _resourceIds;
        private IConfidentialClientApplication App;

        public MyAuthorizationClient(IMyAuthenticationConfig MyAuthenticationConfig)
        {
            _resourceIds = new string[] { MyAuthenticationConfig.MyApimResourceID };

            App = ConfidentialClientApplicationBuilder.Create(MyAuthenticationConfig.MyApimClientID)
                .WithClientSecret(MyAuthenticationConfig.MyApimClientSecret)
                .WithAuthority(new Uri(MyAuthenticationConfig.Authority))
                .Build();
        }

        public async Task<AuthenticationResult> GetMyAccessTokenResultAsync()
        {
            AuthenticationResult result = null;

            try
            {
                result = await App.AcquireTokenForClient(_resourceIds).ExecuteAsync().ConfigureAwait(continueOnCapturedContext:false);
            }
            catch(MsalClientException ex)
            {
                ...
            }
            return result;            
    }
}

}

The issue I'm having is that in the await call, it never returns. The debugger doesn't resume control and the application comes to the foreground as if it continued running. Im unable to interrogate the results of result, and I've already configured the await to not continue.

I reviewed this great thread but it am not getting any solutions for my scenario: Async call with await in HttpClient never returns

2 Answers

Your code:

try
{
    result = await App.AcquireTokenForClient(_resourceIds).ExecuteAsync().ConfigureAwait(continueOnCapturedContext:false);
}

Remove the await and use .Result instead of .ConfigureAwait():

try
{
    result = App.AcquireTokenForClient(_resourceIds).ExecuteAsync().Result;
}

When I did this, the debugger actually caught an exception instead of closing abruptly. For my situation, turns out my scopes (aka _resourceIds in your code) were wrong. The scope that actually worked for my use case:

private string[] Scopes = new[]
{
    "https://graph.microsoft.com/.default"
};

The problem is that I wasn't catching the general exception. The following allowed me to discover my issue, which is that I didn't have the correct scope:

public async Task<AuthenticationResult> GetMyAccessTokenResultAsync()
{
    AuthenticationResult result = null;

    try
    {
        result = await App.AcquireTokenForClient(_resourceIds).ExecuteAsync();
    }
    catch(MsalClientException ex)
    {
        ...
    }
    catch(Exception ex)
    {
        ...
    }

    return result;            
}
Related