Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Token Acquisition Fails Without HttpContext #273

Closed
8 tasks
nickboucher opened this issue Jun 30, 2020 · 4 comments
Closed
8 tasks

[Bug] Token Acquisition Fails Without HttpContext #273

nickboucher opened this issue Jun 30, 2020 · 4 comments
Labels
enhancement New feature or request P1

Comments

@nickboucher
Copy link

Which Version of Microsoft Identity Web are you using ?
0.1.5-preview

Where is the issue?

  • Web App
    • Sign-in users
    • Sign-in users and call web APIs
  • Web API
    • Protected web APIs (Validating tokens)
    • Protected web APIs (Validating scopes)
    • Protected web APIs call downstream web APIs
  • Token cache serialization
    • In Memory caches
    • Session caches
    • Distributed caches

[X] Other:

When token acquisition methods are invoked on the ITokenAcquisition supplied by DI outside of a valid HttpContext, these methods cause an exception. This is because the TokenAcquisition implementation makes reference to the properties of HttpContext without providing adequate null coalescence. While the package was likely designed to be used in the context of a valid HttpContext, there are scenarios in which the context will be null. The most notable example are Azure App Services WebJobs without Http Triggers. More specifically, consider a Web Job running on a Timer Trigger to perform an operation that requires AAD authentication, such as connecting to a Kusto cluster via AAD auth. In this context, when a method such as GetAccessTokenForAppAsync is invoked, it will trigger a NullReferenceException.

Is this a new or existing app?
This is a new app or experiment

Repro

  1. Create an Azure WebJob v3 C# .NET Core app with a TimerTrigger function.
  2. Add the appropriate AzureAd keys into the config, such as via appsettings.json.
  3. Create a standard ConfigureServices function with the following contents:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
     // MSAL based authentication initiation
    services.AddSignIn(Configuration);

    // Token acquisition service based on MSAL.NET
    services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { "YOUR_SCOPE/.default" })
        .AddInMemoryTokenCaches();
    // ...
}
  1. Attempt to retrieve an access token for the application:
string token = tokenAcquisition.GetAccessTokenForAppAsync(new string[] { "YOUR_SCOPE/.default" }).Result;

Expected behavior
Retrieve an access token.

Actual behavior
Null Reference Exception

Possible Solution
Add null coalescence logic to src/Microsoft.Identity.Web/TokenAcquisition.cs:BuildConfidentialClientApplicationAsync. This could be accomplished by allowing a redirect uri to be passed into the function via any means other than extraction from HttpContext.

Additional context/ Logs / Screenshots
Temporary workaround is to manually construct an HttpContext before token acquisition:

if (httpContextAccessor.HttpContext is null)
{
    httpContextAccessor.HttpContext = new DefaultHttpContext();
    httpContextAccessor.HttpContext.Request.Scheme = "https";
    httpContextAccessor.HttpContext.Request.Host = new HostString("localhost");
}

string token = tokenAcquisition.GetAccessTokenForAppAsync(new string[] { "YOUR_SCOPE/.default" }).Result;

This temporary solution is a hack and should be avoided to prevent future breakage when package internals are updated.

Note: This is a first-party Microsoft issue. Please feel free to lookup my alias and ping me on teams for an internal example.

@jmprieur
Copy link
Collaborator

Thanks for reporting @nickboucher
In your scenario, how would Microsoft.Identity.Web know the user if there is no HttpContext when it's called by a web hook?

@jmprieur jmprieur added the enhancement New feature or request label Jun 30, 2020
@jmprieur jmprieur added this to the [6] Support new scenarios milestone Jun 30, 2020
@nickboucher
Copy link
Author

Hi @jmprieur -- thanks for the quick response. The app wouldn't know who the user is, but in this scenario there is no user. I'm specifically interested in the GetAccessTokenForAppAsync method, which acquires an access token on the behalf of the application (not a specific user).

@jmprieur
Copy link
Collaborator

jmprieur commented Jul 1, 2020

Oh, sorry, @nickboucher, I thought I had read GetAccessTokenForUser, yesterday.

@jennyf19
Copy link
Collaborator

Included in 0.2.0-preview release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request P1
Projects
None yet
Development

No branches or pull requests

3 participants