dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.07k stars 9.9k forks source link

Blazor TypeClient `AddHttpMessageHandler` emits `InvalidOperationException` (ValueFactory attempted to access the Value property of this instance.) #33787

Open ibocon opened 3 years ago

ibocon commented 3 years ago

Describe the bug

I use typed HttpClient with OIDC authentication like below,

// Blazor WebAssembly 'Program.cs'
public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<App>("#app");

    builder.Services.AddHttpClient<ApplicationHttpClient>(nameof(ApplicationHttpClient), client =>
    {
        client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
    }).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

    builder.Services.AddScoped(serviceProvider =>
    {
        return serviceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(nameof(ApplicationHttpClient));
    });

    builder.Services.AddOidcAuthentication<RemoteAuthenticationState, RemoteUserAccount>(options =>
    {
        builder.Configuration.Bind("Google", options.ProviderOptions);
        options.ProviderOptions.DefaultScopes.Add("email");
    }).AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount, CustomAccountClaimsPrincipalFactory>();

    await builder.Build().RunAsync();
}

I met below exceptions if I build and run.

If I comment out AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(), it works well like before.

To Reproduce

Github

  1. Run 'TypedHttpClient.Server'
  2. Navigate to 'FetchData' menu
  3. View console error message.

Exceptions (if any)

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ValueFactory attempted to access the Value property of this instance.
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode) in System.Private.CoreLib.dll:token 0x6000fa7+0x43
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) in System.Private.CoreLib.dll:token 0x6000fa8+0x22
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue() in System.Private.CoreLib.dll:token 0x6000fad+0x74
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value() in System.Private.CoreLib.dll:token 0x6000fb3+0xa
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name) in Microsoft.Extensions.Http.dll:token 0x6000065+0xe
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name) in Microsoft.Extensions.Http.dll:token 0x6000064+0xe

Further technical details

.NET 6.0.100-preview.5 21302.13
Visual Studio 2019 16.10.2

.NET SDK(global.json):
 Version:   6.0.100-preview.5.21302.13
 Commit:    d6380bcae7

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100-preview.5.21302.13\

Host (useful for support):
  Version: 6.0.0-preview.5.21301.5
  Commit:  ec3e0b276b

.NET SDKs installed:
  3.1.402 [C:\Program Files\dotnet\sdk]
  5.0.100 [C:\Program Files\dotnet\sdk]
  5.0.301 [C:\Program Files\dotnet\sdk]
  6.0.100-preview.4.21255.9 [C:\Program Files\dotnet\sdk]
  6.0.100-preview.5.21302.13 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.4.21253.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.5.21301.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.4.21253.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.5.21301.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.0-preview.4.21254.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.0-preview.5.21301.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
ibocon commented 3 years ago

Exception comes from DefaultHttpClientFactory.cs.

// Microsoft.Extensions.Http.DefaultHttpClientFactory.cs
public HttpMessageHandler CreateHandler(string name)
{
    if (name == null)
    {
        throw new ArgumentNullException(nameof(name));
    }

    // Here
    ActiveHandlerTrackingEntry entry = _activeHandlers.GetOrAdd(name, _entryFactory).Value;

    StartHandlerEntryTimer(entry);

    return entry.Handler;
}

Should I report to runtime because it is in Microsoft.Extensions.Http namespace?

ibocon commented 3 years ago

I test AddHttpMessageHandler method with NoobHandler like below.

public class NoobHandler : DelegatingHandler
{

}

Instead BaseAddressAuthorizationMessageHandler, add NoobHandler works.

builder.Services.AddScoped<NoobHandler>();
builder.Services.AddHttpClient<WeatherForecastClient>(nameof(WeatherForecastClient),
    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<NoobHandler>();

Therefore, I am suspecting BaseAddressAuthorizationMessageHandler constructor didn't create a instance, but DefaultHttpClientFactory try to access value.

ghost commented 3 years ago

Thanks for contacting us. We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

gingters commented 2 years ago

FYI: This is also the case in .NET 5.

gingters commented 2 years ago

Additional info: This is a complete show-stopper for WebAssembly.Authentication. You can't request apis with an access token when you can't get a HttpClient that can attach the token.

This seemed to work in 3.2 but not in 5 anymore.

TanayParikh commented 2 years ago

Just some notes;

CreateHandler is called here: https://source.dot.net/#Microsoft.Extensions.Http/DefaultHttpClientFactory.cs,143

If valueFactory was null we'd get a null ref exception here: https://source.dot.net/#System.Collections.Concurrent/System/Collections/Concurrent/ConcurrentDictionary.cs,1153

We get an System.InvalidOperationException instead.

Full Exception:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ValueFactory attempted to access the Value property of this instance.
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value()
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
   at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__DisplayClass10_0`1[[TypedHttpClient.Client.WeatherForecastClient, TypedHttpClient.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<AddTypedClientCore>b__0(IServiceProvider s)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__1(ServiceProviderEngineScope p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[AuthenticationStateProvider](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.WebAssemblyAuthenticationServiceCollectionExtensions.<>c__0`3[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.OidcProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].<AddRemoteAuthentication>b__0_1(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__1(ServiceProviderEngineScope p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[BaseAddressAuthorizationMessageHandler](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__4`1[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].<AddHttpMessageHandler>b__4_1(HttpMessageHandlerBuilder b)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass17_0.<CreateHandlerEntry>g__Configure|0(HttpMessageHandlerBuilder b)
   at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass3_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass14_0.<.ctor>b__1()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value()
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
   at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__DisplayClass10_0`1[[TypedHttpClient.Client.WeatherForecastClient, TypedHttpClient.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<AddTypedClientCore>b__0(IServiceProvider s)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__1(ServiceProviderEngineScope p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Components.ComponentFactory.<>c__DisplayClass6_0.<CreateInitializer>g__Initialize|2(IServiceProvider serviceProvider, IComponent component)
   at Microsoft.AspNetCore.Components.ComponentFactory.PerformPropertyInjection(IServiceProvider serviceProvider, IComponent instance)
   at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateComponent(Type componentType)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& frame, Int32 parentComponentId)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
ClumsyPenguin commented 2 years ago

I also run against this issue, this is a real issue for me , since i proxy all our blobstorage image download and upload REST calls trough our API and the API itselfs download and pass the Stream. Since i cannot secure my endpoint now everybody can in theory access my images. Is there a workaround for this issue yet?

hellfirehd commented 2 years ago

Are you seriously putting this off until .NET 7? This is a complete showstopper for me. I at least need a workaround!

hellfirehd commented 2 years ago

CreateHandler is called here: https://source.dot.net/#Microsoft.Extensions.Http/DefaultHttpClientFactory.cs,143

Looks like this:

ActiveHandlerTrackingEntry entry = _activeHandlers.GetOrAdd(name, _entryFactory).Value;

Where _entryFactory is this:

_entryFactory = (name) =>
{
    return new Lazy<ActiveHandlerTrackingEntry>(() =>
    {
        return CreateHandlerEntry(name);
    }, LazyThreadSafetyMode.ExecutionAndPublication);
};

What is the point of using Lazy<T> if you immediately call .Value on it after adding it to the _activeHandlers collection? Can this issue be avoided entirely by not using Lazy<T>?

solalem commented 2 years ago

Any update on this? Please, this is urgent. A client app that can't connect to API service? This is a real show stopper

pszittyay commented 2 years ago

Any workaround? We have a similar situation with the same error using Net Core 5

solalem commented 2 years ago

I fixed my issue by leaving out registration of HttpClientFactory CreateClient configuration. Comment out this part...

   //builder.Services.AddScoped(serviceProvider =>
   // {
   //     return serviceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(nameof(ApplicationHttpClient));
   //});

Then instead of using HttpClient inside components and service classes, I inject IHttpClientFactory itself and create client objects there, like

        public HttpService(IHttpClientFactory httpClientFactory)
        {
            _httpClient = httpClientFactory.CreateClient("WebAPI");
        }

Hope this helps

fehrinjt commented 2 years ago

We are also having issues with this. I tried solalem's suggestion but that didn't have any affect for us.

However I did find a workaround (it's sloppy though):

In your custom ClaimsPrincipalFactory, use IAccessTokenProviderAccessor to get the access token and then pass that as a parameter to any services that need it, and they have to attach it manually to their outgoing requests:

var accessTokenResult = await TokenProvider.RequestAccessToken();
            var accessToken = string.Empty;

            if (accessTokenResult.TryGetToken(out var token))
            {
                accessToken = token.Value;
            }

            if (accessToken.Length < 1)
            {
                return user;
            }

            // Pass on the token to any services that need it
            var userInfo = await userInfoService.UserInfo(accessToken);
Gareth064 commented 2 years ago

Just to add my pain here... this is what I have configured as part of a Blazor WASM Hosted solution and get the same error

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ValueFactory attempted to access the Value property of this instance.
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value()
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
   at Program.<>c.<<Main>$>b__0_1(IServiceProvider sp) in C:\code\Solution\src\Client\Program.cs:line 28

Line 28 is this line from Program.cs

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("CHG.Solution.ServerAPI"));

Program.cs (trimmed for brefity)

   var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddHttpClient("CHG.Solution.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("CHG.Solution.ServerAPI"));

builder.Services.AddBlazoredLocalStorage();
builder.Services.AddTransient<IUserProfileService, UserProfileService>();
builder.Services.AddScoped<IApiBroker, ApiBroker>();
builder.Services.AddSingleton<CurrentUserProfileState>();

builder.Services.AddMudServices(config =>
    {
        config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.TopCenter;
    }
);

builder.Services.AddMsalAuthentication<RemoteAuthenticationState, AuthUserAccount>(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes.Add("api://8d6feec4-d25d-47ac-afa0-15ba8ff293b7/API.Access");
    options.UserOptions.RoleClaim = "roles";
}).AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, AuthUserAccount, UserAccountFactory>();

await builder.Build().RunAsync();

UserAccountFactory.cs

public class UserAccountFactory : AccountClaimsPrincipalFactory<AuthUserAccount>
{
    private readonly CurrentUserProfileState currentUserProfileState;
    private readonly IUserProfileService userProfileService;

    public UserAccountFactory(NavigationManager navigationManager, 
        CurrentUserProfileState currentUserProfileState,
        IUserProfileService userProfileService,
        IAccessTokenProviderAccessor accessor) : base(accessor)
    {
        this.currentUserProfileState = currentUserProfileState;
        this.userProfileService = userProfileService;
    }

    public async override ValueTask<ClaimsPrincipal> CreateUserAsync(
            AuthUserAccount account, RemoteAuthenticationUserOptions options)
    {
        var initialUser = await base.CreateUserAsync(account, options);

        if (initialUser.Identity.IsAuthenticated)
        {
            foreach (var value in account.Roles)
            {
                ((ClaimsIdentity)initialUser.Identity)
                    .AddClaim(new Claim("roles", value));

                currentUserProfileState.UserProfileState.Roles.Append(value);
            }

            foreach (var value in account.Groups)
            {
                ((ClaimsIdentity)initialUser.Identity)
                    .AddClaim(new Claim("groups", value));

                currentUserProfileState.UserProfileState.Groups.Append(value);
            }

            var userProfile = await userProfileService.RetrieveCurrentUserProfileAsync();

            if (userProfile is not null)
            {
                currentUserProfileState.UserProfileState = userProfile;
            }
        }
        return initialUser;
    }

UserProfileService.cs

    public class UserProfileService : IUserProfileService
    {
        private readonly IApiBroker api;

        public UserProfileService(IApiBroker api) =>
            this.api = api;

        public async ValueTask<UserProfile> RetrieveCurrentUserProfileAsync() =>
            var data = await api.GetCurrentUserProfileAsync();
    }

ApiBroker.cs (includes the methods to call my back end webserivce.)

    public partial class ApiBroker : IApiBroker
    {
        private readonly HttpClient client;

        public ApiBroker(HttpClient httpClient)
        {
            this.client = httpClient;
        }
VahidN commented 2 years ago

This exception is a sign of having a circular dependency to the HttpClient itself somewhere in the tree of the injected dependencies of BaseAddressAuthorizationMessageHandler.

ghost commented 1 year ago

Thanks for contacting us. We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

tnking83 commented 1 year ago

I found this issue once I added a custom 'AccountClaimsPrinicipalFactory'. The issue only presents itself if I inject my HttpClient into the custom account class. I fixed my issue by creating a separate instance of the HttpClient. I used this sample as a reference.

This way I can continue to inject my HttpClient everywhere else in my app.

ardalis commented 1 year ago

Just ran into this today setting up BlazorWebAssembly->API-with-Identity-Server in 7.0.4. The base template (File New Project, Blazor WebAssembly, Add Authentication, Individual Accounts) has this:

using BlazorApp1.Client;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddHttpClient("BlazorApp1.ServerAPI", client => 
    client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
        .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient("BlazorApp1.ServerAPI"));

builder.Services.AddApiAuthorization();

await builder.Build().RunAsync();

It works fine. My program.cs code isn't that much different:

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

string clientName = "ClosetPro.Blazor.WebApi";
builder.Services.AddHttpClient(clientName, client =>
    client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
        .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

// Supply HttpClient instances that include access tokens when making
// requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient(clientName));
// NOTE: Hitting this issue: https://github.com/dotnet/aspnetcore/issues/33787

builder.Services.AddApiAuthorization();
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

await builder.Build().RunAsync();

But when I try to integrate it into my actual ASP.NET Core application, I get this error:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ValueFactory attempted to access the Value property of this instance.
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value()
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
   at Program.<>c.<<Main>$>b__0_1(IServiceProvider sp) in C:\dev\clients\ClosetPro\ClosetPro.Blazor\src\ClosetPro.Blazor.WebAssembly\Client\Program.cs:line 36
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass4_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[AuthenticationStateProvider](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.WebAssemblyAuthenticationServiceCollectionExtensions.<>c__0`3[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].<AddRemoteAuthentication>b__0_0(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass4_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[BaseAddressAuthorizationMessageHandler](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__4`1[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].<AddHttpMessageHandler>b__4_1(HttpMessageHandlerBuilder b)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass17_0.<CreateHandlerEntry>g__Configure|0(HttpMessageHandlerBuilder b)
   at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass3_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass14_0.<.ctor>b__1()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue()
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value()
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
   at Program.<>c.<<Main>$>b__0_1(IServiceProvider sp) in C:\dev\clients\ClosetPro\ClosetPro.Blazor\src\ClosetPro.Blazor.WebAssembly\Client\Program.cs:line 36
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass4_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Components.ComponentFactory.<>c__DisplayClass7_0.<CreateInitializer>g__Initialize|1(IServiceProvider serviceProvider, IComponent component)
   at Microsoft.AspNetCore.Components.ComponentFactory.PerformPropertyInjection(IServiceProvider serviceProvider, IComponent instance)
   at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateComponent(Type componentType)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& frame, Int32 parentComponentId)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

Any advice or workarounds while hopefully a fix comes in v8?

MatteoZampariniDev commented 11 months ago

I have the same error when I register a custom AuthenticationStateProvider that requires the HttpClient or another service where it is injected.

In my case the HttpClient is injected in an auto-generated class by NSwag. I managed to fix it by changing the NSwag configuration and I now create the HttpClient from a base class instead of using the service injection.

public class ApiClientOptions
{
    public string BaseAddress { get; set; } = string.Empty;
}

public partial class BaseApiClient
{
    private readonly ApiClientOptions _configuration;

    public BaseApiClient(ApiClientOptions configuration)
    {
        _configuration = configuration;
    }

    protected Task<HttpClient> CreateHttpClientAsync(CancellationToken cancellationToken)
    {
        return Task.Run(() =>
        {
            var client = new HttpClient();
            client.BaseAddress = new Uri(_configuration.BaseAddress);

            return client;
        });
    }
}
dschuesae commented 10 months ago

Same issue here with .net 8.0 rc1

ghost commented 10 months ago

To learn more about what this message means, what to expect next, and how this issue will be handled you can read our Triage Process document. We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. Because it's not immediately obvious what is causing this behavior, we would like to keep this around to collect more feedback, which can later help us determine how to handle this. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact work.

klemmchr commented 10 months ago

Any updates on this? This makes MSAL in Blazor basically useless.

DominikErnst commented 10 months ago

I've been struggling here for weeks, .Net 7, WASM, RestAPi, Bearer Token, MSAL, Azure Entra ID, Swashbuckle, NSwag. I think one problem is using navigationManager.BaseUri in BaseAddressAuthorizationMessageHandler, because I separated WASM and RestApi.

`// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license.

using System.Net.Http;

namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication;

///

/// A that attaches access tokens to outgoing instances. /// Access tokens will only be added when the request URI is within the application's base URI. /// public class BaseAddressAuthorizationMessageHandler : AuthorizationMessageHandler { /// /// Initializes a new instance of . /// /// The to use for requesting tokens. /// The used to compute the base address. public BaseAddressAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigationManager) : base(provider, navigationManager) { ConfigureHandler(new[] { navigationManager.BaseUri }); } } `

UPDATE: Now I can seperate WASM und RestAPi:

`using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

namespace AMS.App { ///

/// A that attaches access tokens to outgoing instances. /// Access tokens will only be added when the request URI is within the application's base URI. /// public class AmsAddressAuthorizationMessageHandler : AuthorizationMessageHandler { public AmsAddressAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigationManager, IConfiguration configuration) : base(provider, navigationManager) { //ConfigureHandler(new[] { navigationManager.BaseUri }); ConfigureHandler(new[] { configuration.GetRequiredSection("AMSRestApi:url").Value }); } } }`

madnik7 commented 9 months ago

A circular dependency injection of HttpClient could cause this. Such as this:

        builder.Services.AddScoped<AuthenticationService>();
        builder.Services.AddScoped<AppHttpMessageHandler>();
        builder.Services.AddHttpClient("MyApi", client => client.BaseAddress = new Uri(ApiBaseAddress))
          .AddHttpMessageHandler<AppHttpMessageHandler>();

If you try to inject HttpClient to AuthenticationService or AppHttpMessageHandler, you will get this error: ValueFactory attempted to access the Value property of this instance

Try using the IHttpClientFactory independent service to solve this issue.

ghost commented 8 months ago

To learn more about what this message means, what to expect next, and how this issue will be handled you can read our Triage Process document. We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. Because it's not immediately obvious what is causing this behavior, we would like to keep this around to collect more feedback, which can later help us determine how to handle this. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact work.

vugarli commented 6 months ago

In my case, I also had a circular dependency situation (I was using the HttpClient in the MessageHandler which was added to the same HttpClient). Removing it fixed the issue.

koureasstavros commented 1 month ago

this today setting up BlazorWebAssembly->API-with-Identity-Server in 7.0.4. The base template (File New Project, Blazor WebAssembly, Add Authentication, Individual Accounts) has this:

I am using Blazor Hosted WebAssembly in .NET 8 with client and server projects, my intention is to use Keycloak with CustomAuthenticationStateProvider because I have also basic authentication using database credentials and therefore need the CustomAuthenticationStateProvider implementation, but lets make it simple only using keycloak:

In Client side I register HttpClient as follow:

var httpClientName = "Default";

builder.Services.AddHttpClient(httpClientName, client => {
        client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
    })
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); 

builder.Services.AddScoped(
    sp => sp.GetRequiredService<IHttpClientFactory>()
        .CreateClient(httpClientName));

.AddHttpMessageHandler(); is required in order server to be able to validate from it's side the tokens and make [Authorize] attribute to work into Controllers.

In Client side I register OIDC Authentication as follow:

builder.Services.AddOidcAuthentication(options =>
{
    options.ProviderOptions.Authority = Parameters.transportation.openids_address_real;
    options.ProviderOptions.MetadataUrl = Parameters.transportation.openids_address_conf;
    options.ProviderOptions.ClientId = Parameters.transportation.openids_client;
    options.ProviderOptions.ResponseType = "id_token token";
    //options.ProviderOptions.ResponseType = "access_token";
    //options.ProviderOptions.RedirectUri = "/"; DEFINED DYNAMICALLY FROM AUTHENTICATION RAZOR

    options.UserOptions.NameClaim = "preferred_username"; //MAPS THE CLAIM WITH THE IDENTITY SPEC
    options.UserOptions.RoleClaim = "roles"; //MAPS THE CLAIM WITH THE IDENTITY SPEC
    options.UserOptions.ScopeClaim = "scope"; //MAPS THE CLAIM WITH THE IDENTITY SPEC
    options.UserOptions.AuthenticationType = "keycloak"; //MAPS THE CLAIM WITH THE IDENTITY SPEC
});

Now the above code works but as soon as I register the CustomAuthStateProvider as follow: builder.Services.AddScoped<AuthenticationStateProvider, KeycloakAuthStateProvider>();

I get the same issue: blazor Error: One or more errors occurred. (ValueFactory attempted to access the Value property of this instance.)

After days of tests, I concluded that the following combination produces the error: .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); and builder.Services.AddScoped<AuthenticationStateProvider, KeycloakAuthStateProvider>();

But in my case it is essential to use both as I need Custom Authentication State Provider and the auth need to be transported into server side in order the controllers to accept authenticated requests.