AzureAD / azure-activedirectory-library-for-dotnet

ADAL authentication libraries for .net
http://aka.ms/aaddev
MIT License
358 stars 214 forks source link

NullReferenceException in AuthenticationContext.AcquireToken 2.28.3.860 #583

Closed EricHirst closed 7 years ago

EricHirst commented 7 years ago

See http://stackoverflow.com/questions/41371085/nullreferenceexception-in-microsoft-identitymodel-clients-activedirectory-acquir .

I'm running into the following error trying to get the MSFT Power BI SDK samples working:

System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.RunAsyncTask[T](Task`1 task) at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.AcquireToken(String resource, String clientId, Uri redirectUri, PromptBehavior promptBehavior) at PowerBISample.Application.Main(String[] args) in \noxfile\users\ehirst\documents\visual studio 2015\Projects\PowerBISample\PowerBISample\Program.cs:line 18

Repro code is as follows:

using System;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

public class Application
{
public static void Main(string[] args)
{
    try
    {
        string clientID = "abcdef01-1234-1234-abcd-abcdabcd1234"; // TODO: actual Azure client ID
        string redirectUri = "https://acmecorporation.okta.com/login/do-login"; // TODO: actual redirect
        string resourceUri = "https://analysis.windows.net/powerbi/api";
        string authorityUri = "https://login.windows.net/common/oauth2/authorize";

        AuthenticationContext authContext = new AuthenticationContext(authorityUri);
        AuthenticationResult ar = authContext.AcquireToken(
                resourceUri,
                clientID,
                new Uri(redirectUri),
                PromptBehavior.RefreshSession);
        string token = ar.AccessToken;
        Console.WriteLine("Success: " + token);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}
}

I'll update this issue as I learn more -- maybe there's something about how our auth provider (Okta) is configured that's hitting an untested code path. I'd also welcome feedback (here or on SO) on how to port this code to ADAL 3.x; that would be a perfectly good workaround from my perspective if the bug is already fixed there.

kpanwar commented 7 years ago

@EricHirst - We only support async calls in ADAL v3. Equivalent ADAL call would be var result = await context.AcquireTokenAsync(resourceUri, clientID, new Uri(redirectUri), new PlatformParameters(PromptBehavior.RefreshSession));

EricHirst commented 7 years ago

Thanks @kpanwar -- I think that was the mapping I was looking for.

Regarding the null reference exception, I've repro'd this in the debugger now after stripping out all the MSFT signing code from 2.28.3 and getting it to build on my machine. It's coming in AcquireTokenInteractiveHandler.cs, VerifyAuthorizationResult(), on line 197:

if (this.authorizationResult.Status != AuthorizationStatus.Success)

because this.authorizationResult is null. So far I have no idea why it's null.

EricHirst commented 7 years ago

It's null because the resultUri associated with "https://acmecorporation.okta.com/login/do-login" (or my company's equivalent) has a Query value of string.Empty. So line 191 of OAuth2Response.cd, (ParseAuthorizeResponse), is seeing resultData == "" and skipping the assignment of an AuthorizationResult value.

Throw a useful exception here instead of quietly failing?

EricHirst commented 7 years ago

I've made changes to my code, most notably changing the value of resultUri to "https://login.live.com/oauth20_desktop.srf", and my app works now.

Regarding the NullReferenceException bug, it's already fixed in the current version of ADAL; newer versions throw slightly more useful exceptions here instead of crashing The better exception wasn't really enough in my case however; it could perhaps be improved to better tell me how to fix my bad resultUri. Thanks for your help with this @kpanwar .