question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Bug] Microsoft.Identity.Web should not call BuildServiceProvider

See original GitHub issue

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

Where is the issue?

  • Web App
    • [x ] Sign-in users
  • Web API
    • [x ] Protected web APIs (Validating tokens)

Repro See:

https://github.com/AzureAD/microsoft-identity-web/blob/5bc881bb6088f92db6e157f839bffb924627b215/src/Microsoft.Identity.Web/WebApiAuthenticationBuilderExtensions.cs#L145

https://github.com/AzureAD/microsoft-identity-web/blob/5bc881bb6088f92db6e157f839bffb924627b215/src/Microsoft.Identity.Web/WebAppAuthenticationBuilderExtensions.cs#L202

Expected behavior NEVER call BuildServiceProvider.

Actual behavior Microsoft.Identity.Web calls BuildServiceProvider

Discussion

  • It’s a MUST FIX

  • In NET 5.0, there is an overload of AddJwtBearer / AddOpenIdConnect with a service that you want to inject

  • We need to come-up with alternatives for 3.0. @Tratcher will help

  • in addition raise an issue with ASP.NET Core to have these diagnostics available by default without wrapping the events.

Possible design (but feel free to do differently)

  1. Add a constant in the Microsoft.Identity.Web.csproj file depending on the TargetFramework (maybe something like:

      <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
        <DefineConstants>$(DefineConstants);DOTNET_CORE_31</DefineConstants>
      </PropertyGroup>
    
  2. Based on the constant use one form of the other of AddOpenIdConnect and AddJwtBearer. For instance for AddOpenIdConnect we could have something like the following:

    #if DOTNET_CORE_31
             builder.AddOpenIdConnect(openIdConnectScheme, options =>
             {
              // Todo: replace by the work around that @Tratcher will provider
              IServiceProvider serviceProvider = builder.Services.BuildServiceProvider();
    #else
             builder.AddOpenIdConnect<IServiceProvider>(openIdConnectScheme, (options, serviceProvider) =>
             {
    #endif
    

Note that the aspnetcoreapp3.1 case would still use the BuildServiceProvider until Chris provides a workaround

  1. In the section garded by the subscribeToXXXMiddlewareDiagnosticsEvents boolean, just use the serviceProvider to call GetRequiredService<> For instance for the OIDC case, something like:

     var diags = serviceProvider.GetRequiredService<IOpenIdConnectMiddlewareDiagnostics>();
    
  2. Consider doing #239 soon after this one, as it leverages similar mechanisms

  3. Follow-up with @Tratcher for the NET 3.1 work around to populate the service provider in the case of netcore3.1

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
jmprieurcommented, Jul 1, 2020

So I understand that the section in WebApiAuthenticationBuilderExtensions.cs could be:

#if DOTNET_CORE_31
            // Change the authentication configuration to accommodate the Microsoft identity platform endpoint (v2.0).
            builder.AddJwtBearer(jwtBearerScheme, options => { });
            builder.Services.AddOptions<JwtBearerOptions>(jwtBearerScheme)
                .Configure<IServiceProvider>((options, serviceProvider) =>
            {
#else
            builder.AddJwtBearer<IServiceProvider>(jwtBearerScheme, (options, serviceProvider) =>
            {
#endif

And in WebAppAuthenticationBuilderExtensions.cs, it could be:

#if DOTNET_CORE_31
            builder.AddOpenIdConnect(openIdConnectScheme, options => { });
            builder.Services.AddOptions<OpenIdConnectOptions>(openIdConnectScheme)
                .Configure<IServiceProvider>((options, serviceProvider) =>
                {
#else
            builder.AddOpenIdConnect<IServiceProvider>(openIdConnectScheme, (options, serviceProvider) =>
            {
#endif

@jennyf19, moving back to “in progress” now that Chris has shared the work around for .NET Core 3.1

1reaction
Tratchercommented, Jun 30, 2020

https://github.com/dotnet/aspnetcore/issues/18772#issuecomment-588302416 This should work in prior versions:

services.AddOptions<OpenIdConnectOptions>(authSchemeName)
  .Configure<IOpenIdConnectMiddlewareDiagnostics>((options, diagnostics) =>
  {
  });

In fact, you could do it in both versions and avoid the #ifs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ASP0000: Do not call 'IServiceCollection. ...
A call to BuildServiceProvider was detected in the application start up code. Rule description. Calling 'BuildServiceProvider' from application ...
Read more >
Calling 'BuildServiceProvider' from application code results ...
ASP.NET Core will build the ServiceProvider automatically at runtime, therefore don't call the BuildServiceProvider() manually. I read Adam ...
Read more >
Accessing Page Data during Startup
I need the IContentLoader in the ConfigureContainer method, but can only get it in the Initialize method. Each time, the site will not...
Read more >
Understanding Dependency Injection in .NET Core
High-level modules should not depend on low-level modules. ... In .NET Core, the dependencies managed by the container are called services.
Read more >
Cannot Consume Scoped Service From Singleton
Scoped means that a new instance will be created essentially per page load (Atleast that's the “scope” within ASP.NET Core). services.AddScoped<MyFatherService> ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found