Search code examples
asp.net-mvcazure-active-directorymicrosoft-graph-apiadal

Null Reference Exception in System.Web isn't caught even with try/catch - only occurs on first run of this code, subsequent runs work fine


So I have this bit of code that gets a token from Azure Active Directory. When this bit runs the first time after the server starts, it's crashing with a null reference exception. The exception occurring is recorded in the output window, but the exception itself isn't caught by my code.

When I use the debugger to step through this code, it simply does not continue past AcquireTokenAsync - It terminates there, with the exception recorded in output, but it's not caught by my try/catch, and there's no way to recover.

There's nothing in here that's null, so I'm at a bit of a loss to explain, especially why this only occurs once after the server is restarted.

Code

    private static async Task<string> getToken() 
    {
        string aadInstance = ConfigurationManager.AppSettings["Authority"];
        string tenant = ConfigurationManager.AppSettings["Tenant"];
        string clientId = ConfigurationManager.AppSettings["ClientId"];
        string clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
        string resource = ConfigurationManager.AppSettings["GraphResourceUri"];
        string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
        AuthenticationContext authContext = new AuthenticationContext(authority);
        ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
        try
        {
            AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCredential); 
       //anything past here never runs
            return result.AccessToken;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.StackTrace);
        }
        return "";
    }

Edit:

Okay I have a stack trace after messing with exception settings: StackTrace " at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)"


Solution

  • You are experiencing a deadlock issue that you can overcome by using:

    AuthenticationResult result = authContext.AcquireTokenAsync(resource, clientCredential).Result;

    or

    AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCredential).ConfigureAwait(false);

    This issue is caused by blocking on async code.

    For a deeper dive into these topics, you can check here and here

    The issues described in these links are happening somewhere internal to the call to await authContext.AcquireTokenAsync(resource, clientCredential); (code not posted so I can't tell you exactly where)