Skip to content

Exception 'GetAuthenticationStateAsync was called before SetAuthenticationState.' thrown when calling AuthenticationStateProvider.GetAuthenticationStateAsync() method #28684

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

Closed
AFAde opened this issue Dec 16, 2020 · 42 comments
Assignees
Labels
affected-medium This issue impacts approximately half of our customers area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. investigate Priority:1 Work that is critical for the release, but we could probably ship without question severity-major This label is used by an internal tool Status: Resolved
Milestone

Comments

@AFAde
Copy link

AFAde commented Dec 16, 2020

Describe the bug

In my Blazor Server app, exactly as described in this bug report,

'GetAuthenticationStateAsync was called before SetAuthenticationState.'

the GetAuthenticationStateAsync works only if the AuthenticationStateProvider service is synchronously called from a Blazor page.

In any async call running in the background it fails with the mentioned error message.

To Reproduce

Here is a sample repo:
BlazorAppWithAuthenticationError

Just start the application and click on Fetch Data, the exception will be thrown immediately at the line 23 of the AuthTokenHandler class. I am using the HttpClient Factory pattern, which seems to lead to the issue.

Exceptions (if any)

System.InvalidOperationException: GetAuthenticationStateAsync was called before SetAuthenticationState.
   at Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.GetAuthenticationStateAsync()
   at MyClasss.ExecuteAsync
...

Further technical details

  • ASP.NET Core version 5
  • output of dotnet --info
    .NET SDK (reflecting any global.json):
    Version: 5.0.101
    Commit: d05174dc5a

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.101\

Host (useful for support):
Version: 5.0.1
Commit: b02e13abab

.NET SDKs installed:
3.0.100 [C:\Program Files\dotnet\sdk]
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
5.0.101 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.7 [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.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

  • Visual Studio 2019 16.8.3
@blowdart blowdart added the area-blazor Includes: Blazor, Razor Components label Dec 16, 2020
@mkArtakMSFT mkArtakMSFT added this to the Next sprint planning milestone Dec 16, 2020
@ghost
Copy link

ghost commented Dec 16, 2020

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@beausmyth1990
Copy link

I am also getting this issue and I cannot, for the life of me, figure out why. If I inject AuthenticationStateProvider via construction injection into any service and make a call to GetAuthenticationStateAsync() at any point in my code it will throw the exception mentioned by @AFAde. This will even occur when the user is logged-in, so I know that an the AuthenticationState must exist. Any thoughts on what the problem could be?

@maxxhount
Copy link

Im getting the same issue. Any update?

@SteveSandersonMS SteveSandersonMS added affected-medium This issue impacts approximately half of our customers bug This issue describes a behavior which is not expected - a bug. severity-major This label is used by an internal tool labels Jan 26, 2021 — with ASP.NET Core Issue Ranking
@shareonline
Copy link

Same.. Blazor Server side on .NET 5.
Trying to use in a userService together with EF Core and it is periodically failing

@vavdb
Copy link

vavdb commented Feb 28, 2021

I ran into the same issue to get a token. I had to replace it with this to get it working:

        private readonly MicrosoftIdentityConsentAndConditionalAccessHandler _consentHandler;
        private readonly ITokenAcquisition _tokenAcquisition;

...

            var authUser = _consentHandler.User;
            var accessToken = await _tokenAcquisition
                .GetAccessTokenForUserAsync(_scopes, user: authUser)
                .ConfigureAwait(false);

Not sure if I am going to run into any issues.

The issue only seems to occur when I run it in a DelegatingHandler, I can access it fine in the actual HttpClient implementation

@cuperman007
Copy link

I'm hitting same issue. I am using Azure AD for my logins. I have a generic repository pattern where I want to automatically add the current user name to a LastEditedBy field on all records when they are saved.

When injecting AuthenticationStateProvider into the service class, I get the error when calling the GetAuthenticationStateAsync method.

Many resources suggest using IHttpContextAccessor, but this does not work with Azure app service and we are advised not to use here

Is there another suitable work around to access the current user name in a service?

@FelipeCostaGualberto
Copy link

I'm also having this problem, I can't inject AuthenticationStateProvider in my services.
Blazor Server Side with ASP.NET 5.

@mikaelservin
Copy link

I have been developing a Blazor Server application for a few weeks now and tried to add a UserService where I can get the signed in user's identity and all post say you should use AuthenticationStateProvider injected to the service. I tried that but keep getting the error that I first should call SetAuthenticationState.

Is there really no work around for this? Is there any other way to get the identity or username for the signed in user that is possible to use in a service? The UserId is shown in the LoginDisplay component where @context.User.Identity.Name! is used.

@ericjohnston
Copy link

ericjohnston commented Apr 16, 2021

I'm having the same type of issue in a Blazor Server app when trying to use the information from a service by injecting AuthenticationStateProvider. The only workaround I've been able to work out is to use both IHttpContextAccessor and the AuthenticationStateProvider. It's not recommended nor ideal, but it mostly works for my use case.

I'm using the IHttpContextAccessor in middleware to set the properties I need on scoped objects that are injected into the service(s), but I'm using AuthenticationStateProvider in Blazor components, as recommended, where the HttpContext is already disposed.

It definitely feels very hacky and I'm sure it could be done in a much more elegant way than my implementation, but it's what works for now.

I'm assuming this issue impacts anyone building a Blazor Server app that needs user state/context information outside of Blazor components.

@Panzerfury
Copy link

I think this should be a priority.

@mikaelservin
Copy link

Thanks @ericjohnston for the reply. I will try and do something with IHttpContextAccessor even though I understand that it's not recommended. I am new to Blazor and .Net 5 and I am learning the hard way that things don't always work the way I think they should. I spent a couple of hours on this before I found this issue and understood that it was a bug and not something I was doing wrong again.

I hope there is a fix on the way for this and I think someone should write an official work around in the documentation so that people don't have to invent their own solutions.

@beausmyth1990
Copy link

beausmyth1990 commented Jun 1, 2021

I'm having the same type of issue in a Blazor Server app when trying to use the information from a service by injecting AuthenticationStateProvider. The only workaround I've been able to work out is to use both IHttpContextAccessor and the AuthenticationStateProvider. It's not recommended nor ideal, but it mostly works for my use case.

I'm using the IHttpContextAccessor in middleware to set the properties I need on scoped objects that are injected into the service(s), but I'm using AuthenticationStateProvider in Blazor components, as recommended, where the HttpContext is already disposed.

It definitely feels very hacky and I'm sure it could be done in a much more elegant way than my implementation, but it's what works for now.

I'm assuming this issue impacts anyone building a Blazor Server app that needs user state/context information outside of Blazor components.

I believe that it has been mentioned (somewhere in the Docs) that IHttpContextAccessor should NOT be used. Reason being - they might remove it in later versions, and not to mention that Server-Side only uses HTTP to initiate a web socket connection - it's a completely different protocol of communication. Once the socket is open no more HTTP. I fear that this is not a viable workaround. We need this issue addressed - like, now.

@shareonline
Copy link

I'm having the same type of issue in a Blazor Server app when trying to use the information from a service by injecting AuthenticationStateProvider. The only workaround I've been able to work out is to use both IHttpContextAccessor and the AuthenticationStateProvider. It's not recommended nor ideal, but it mostly works for my use case.
I'm using the IHttpContextAccessor in middleware to set the properties I need on scoped objects that are injected into the service(s), but I'm using AuthenticationStateProvider in Blazor components, as recommended, where the HttpContext is already disposed.
It definitely feels very hacky and I'm sure it could be done in a much more elegant way than my implementation, but it's what works for now.
I'm assuming this issue impacts anyone building a Blazor Server app that needs user state/context information outside of Blazor components.

I believe that it has been mentioned (somewhere in the Docs) that IHttpContextAccessor should NOT be used. Reason being - they might remove it in later versions, and not to mention that Server-Side only uses HTTP to initiate a web socket connection - it's a completely different protocol of communication. Once the socket is open no more HTTP. I fear that this is not a viable workaround. We need this issue addressed - like, now.

THIS.. Using the exact same method, and if not recommended or supported we truly need a fix as quick as possible..
It needs to move a little faster with stuff like this in Blazor, if it is to become a mainstream framework. Don't get me wrong development is fast for Blazor and I love it in general, but key issues like this hinders all "real" development that isn't just front pages for companies.

@beausmyth1990
Copy link

@shareonline I performed a quick test today by whipping-up a new Blazor Server-Side proj and injecting the AuthenticationStateProvider into a Scoped service. After calling the GetAuthenticationAsync method of the AutheticationStateProvider I did not get an exception. Could it be that this problem has been solved? Was the fix released in .Net 5? Who knows.

@shareonline
Copy link

@shareonline I performed a quick test today by whipping-up a new Blazor Server-Side proj and injecting the AuthenticationStateProvider into a Scoped service. After calling the GetAuthenticationAsync method of the AutheticationStateProvider I did not get an exception. Could it be that this problem has been solved? Was the fix released in .Net 5? Who knows.

Hmm yeah maybe..
I have only run into the errors when using it with my scoped EF context.
I have solved it by using a transient dbcontext and a scoped service for my userservice. The userservice lives in my frontend project, where my dbcontext lives in my shared/service project. This works and so far so good.

@AFAde
Copy link
Author

AFAde commented Jun 1, 2021

@shareonline I performed a quick test today by whipping-up a new Blazor Server-Side proj and injecting the AuthenticationStateProvider into a Scoped service. After calling the GetAuthenticationAsync method of the AutheticationStateProvider I did not get an exception. Could it be that this problem has been solved? Was the fix released in .Net 5? Who knows.

I am using .NET 5 (5.0.203) and definitely this issue has not been solved, I can still reproduce the error, please take a look at the repository which is mentioned in my first post

@agilenut
Copy link

This issue is still occurring when injecting AuthenticationStateProvider into a DelegatingHandler with latest .Net 5.

We really need a consistent way to get access to the user context. It is silly to have to do one thing when we are in Blazor land and another thing when we have a full HttpContext.

Status or workaround?

@SadPraetor
Copy link

One scenario where I'm encountering this issue consistently, if you call for AuthenticationState from created scope. You create a separate scope in your code, and somewhere under this scope you call GetAuthenticatonStateAsync .
One way to figure out if this is your situation, is to register AuthenticatonStateProvider as singleton (just for this test), if it works fine as singleton, but it fails if it is registered as scoped, that would be a strong indication you are doing this mistake.

@pilcherd
Copy link

pilcherd commented Feb 2, 2023

@mkArtakMSFT This issue needs to stop being bumped. 5-6, 6-7, 7 to now 8.

What is a recommended pattern to use for accessing the user context from a service given that we are told not to use IHttpContextAccessor and AuthenticationStateProvider is not reliably usable when injected using DI? Thanks.

@appsupport-gc
Copy link

Good Question!!

@javiercn
Copy link
Member

javiercn commented Feb 6, 2023

This is currently documented here

@pilcherd
Copy link

pilcherd commented Feb 6, 2023

This is currently documented here

That might work for rendered components that you can override but doesn't work for the sample at the top of this thread.

@javiercn
Copy link
Member

javiercn commented Feb 6, 2023

@pilcherd the example I provided also works for this.

You can't call AuthenticationStateProvider within a delegating handler when using HttpClientFactory because it creates its own scope for the handlers.

The way this is handled is by creating a handler that reads from an async local and having the code that calls into the HttpClient instance set that async local with the right context before the call.

This is also how it works in ASP.NET Core for things like header propagation, where the HeaderPropagationMiddleware sets the context. https://github.com/dotnet/aspnetcore/tree/main/src/Middleware/HeaderPropagation/src

@javiercn javiercn added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label Feb 7, 2023
@ghost
Copy link

ghost commented Feb 7, 2023

Hi @AFAde. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@cedwards-telis
Copy link

@javiercn maybe submit a pull request to the OP's repo so we can see how we are supposed to implement this?

@javiercn
Copy link
Member

javiercn commented Feb 7, 2023

This is the handler; the rest is the same as in the sample in the docs.

public class ContextHandler : DelegatingHandler
{
    public ContextHandler(BlazorContextAccessor accessor)
   {
       _accessor = accessor;
   }

   protected Task SendAsync(HttpRequestMessage request)
   {
       var provider =_accessor.Services.GetRequiredService<AuthenticationStateProvider>();
       ...
   }
}

@MackinnonBuck do you have your sample with HttpClient around?

@AFAde
Copy link
Author

AFAde commented Feb 9, 2023

Hi @javiercn , thanks a lot. By following your suggestions I was able to get the code working. If I get it right, when using pattern like the HttpClientFactory each control needs to inherit from CustomComponentBase, is this right?

One more: if I want to decouple pages/controls the from the core logic - for example, by following the MVVM architectural design pattern - what would be the best approach? In other words, is it possible to decouple the initialization and handling of the BlazorContextAccessor from the control? If yes, how? do you have any sample?

For those who are interested, you can take a look at the repository from the top of this thread, I just pushed the changes.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Feb 9, 2023
@javiercn javiercn added question ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels Feb 15, 2023
@ghost ghost added the Status: Resolved label Feb 15, 2023
@javiercn
Copy link
Member

One more: if I want to decouple pages/controls the from the core logic - for example, by following the MVVM architectural design pattern - what would be the best approach? In other words, is it possible to decouple the initialization and handling of the BlazorContextAccessor from the control? If yes, how? do you have any sample?

There's not a great way of doing this in a centralized way, but that's something we might change in .NET 8.0 as part of
#30287

@ghost
Copy link

ghost commented Feb 16, 2023

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@ghost ghost closed this as completed Feb 16, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Mar 18, 2023
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affected-medium This issue impacts approximately half of our customers area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. investigate Priority:1 Work that is critical for the release, but we could probably ship without question severity-major This label is used by an internal tool Status: Resolved
Projects
None yet
Development

No branches or pull requests