aspnetcore: Blazor TypeClient `AddHttpMessageHandler` emits `InvalidOperationException` (ValueFactory attempted to access the Value property of this instance.)
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
- Run ‘TypedHttpClient.Server’
- Navigate to ‘FetchData’ menu
- 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]
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 9
- Comments: 25 (6 by maintainers)
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:
It works fine. My program.cs code isn’t that much different:
But when I try to integrate it into my actual ASP.NET Core application, I get this error:
Any advice or workarounds while hopefully a fix comes in v8?
This exception is a sign of having a
circular dependencyto theHttpClientitself somewhere in the tree of the injected dependencies ofBaseAddressAuthorizationMessageHandler.A circular dependency injection of HttpClient could cause this. Such as this:
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.
Any workaround? We have a similar situation with the same error using Net Core 5
Any update on this? Please, this is urgent. A client app that can’t connect to API service? This is a real show stopper
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.
Any updates on this? This makes MSAL in Blazor basically useless.
I fixed my issue by leaving out registration of HttpClientFactory CreateClient configuration. Comment out this part…
Then instead of using HttpClient inside components and service classes, I inject IHttpClientFactory itself and create client objects there, like
Hope this helps
Looks like this:
Where
_entryFactoryis this:What is the point of using
Lazy<T>if you immediately call.Valueon it after adding it to the_activeHandlerscollection? Can this issue be avoided entirely by not usingLazy<T>?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?
FYI: This is also the case in .NET 5.
Thanks for contacting us. We’re moving this issue to the
Next sprint planningmilestone 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.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 <see cref="DelegatingHandler"/> that attaches access tokens to outgoing <see cref="HttpResponseMessage"/> 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 <see cref="BaseAddressAuthorizationMessageHandler"/>.
///
/// <param name="provider">The <see cref="IAccessTokenProvider"/> to use for requesting tokens.</param>
/// <param name="navigationManager">The <see cref="NavigationManager"/> used to compute the base address.</param>
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 <see cref="DelegatingHandler"/> that attaches access tokens to outgoing <see cref="HttpResponseMessage"/> 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 });
}
}
}`
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.
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
Line 28 is this line from Program.cs
Program.cs (trimmed for brefity)
UserAccountFactory.cs
UserProfileService.cs
ApiBroker.cs (includes the methods to call my back end webserivce.)
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:
Are you seriously putting this off until .NET 7? This is a complete showstopper for me. I at least need a workaround!