Skip to content

On each circuit connection up, update the User in authentication state #12051

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
SteveSandersonMS opened this issue Jul 10, 2019 · 4 comments
Closed
Assignees
Labels
area-blazor Includes: Blazor, Razor Components Done This issue has been fixed enhancement This issue represents an ask for new feature or an enhancement to an existing one

Comments

@SteveSandersonMS
Copy link
Member

This is for server-side Blazor and will address most of the issues with using Windows authentication.

Currently the built-in internal default FixedAuthenticationStateProvider assumes the authentication state is fixed for the lifetime of the circuit, as its name implies. However this isn't adequate for Windows authentication, as the WindowsPrincipal is connected to underlying OS services and can't continue to be used if the original HTTP request has completed. Trying to call things like IsInRole will throw if the principal has already been disposed, which would happen if:

  • You're using prerendering, in which case the original WindowsPrincipal will have been disposed once the prerendering HTTP request completed
  • Even if you're not using prerendering, if the WebSocket connection was ever lost, or if you're using something else like long polling where the original request isn't retained anyway

To resolve this, we need some extra logic that, whenever the circuit connection becomes up (equivalent to OnConnectionUpAsync on a circuit handler), we grab the latest User from the HubContext (or HttpContext if we must, but HubContext is more correct) and pass it to the built-in authentication state provider, which can update its own internal state and call its own NotifyAuthenticationStateChanged.

Caveat

This will fix most scenarios, but one case will remain: if the user is currently disconnected and some background process is trying to call APIs like IsInRole on their ClaimsPrincipal, this will still throw. There's nothing we can do about that short of adding features at the IIS integration layer, which would have other drawbacks so we might never want to do that. Basically, developers should only be using Windows authentication for intranet apps where transient disconnection is not something that will happen, or they do their own error handling if it does.

@SteveSandersonMS SteveSandersonMS added the area-blazor Includes: Blazor, Razor Components label Jul 10, 2019
@rynowak
Copy link
Member

rynowak commented Jul 10, 2019

connected to underlying OS services and can't continue to be used if the original HTTP request has completed.

How would this work for long-polling though? Since one SignalR connection spans multiple requests that implies that each message (and each long-polling request) has its own principal. Does SignalR do something special here?

@BrennanConroy
Copy link
Member

Does SignalR do something special here?

Yes, we clone the HttpContext and do some special logic for Windows auth.
https://github.com/aspnet/AspNetCore/blob/28f9816d46131c7381e9cadfd47e5c844f0b6fc4/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs#L495

@mkArtakMSFT mkArtakMSFT added this to the 3.0.0-preview9 milestone Jul 10, 2019
@mkArtakMSFT mkArtakMSFT added enhancement This issue represents an ask for new feature or an enhancement to an existing one cost: S labels Jul 10, 2019
@SteveSandersonMS
Copy link
Member Author

How would this work for long-polling though?

If we update the authentication state's ClaimsPrincipal each time we see a new SignalR connection, and we take it from HubCallerContext.User, then we get the same level of support that SignalR itself offers:

  • For websockets, the principal always matches your current connection, so always works whenever you're connected. For Windows authentication specifically, it will throw if you try to evaluate something like IsInRole while disconnected, so you have to not do that.
  • For long polling, the principal is SignalR's cloned one from the start of the current connection (which spans many long-polling requests), so we have the same level of Windows authentication support that SignalR itself offers in that scenario.

@SteveSandersonMS
Copy link
Member Author

SteveSandersonMS commented Jul 24, 2019

Done in #12421

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components Done This issue has been fixed enhancement This issue represents an ask for new feature or an enhancement to an existing one
Projects
None yet
Development

No branches or pull requests

4 participants