Skip to content

Fix Blazor template bug where a logged in user could appear to be unauthenticated #51497

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

Merged
merged 3 commits into from
Oct 20, 2023

Conversation

halter73
Copy link
Member

@halter73 halter73 commented Oct 19, 2023

Description

A customer reported that after enhanced navigation from a WebAssembly-rendered component that does not require authentication state to another WebAssembly-rendered component that does, the client will lose its authentication state. This leads to issues where the server knows the client is authenticated meaning the client can navigate to components that require authentication, but the client thinks the user is unauthenticated for the purposes of rendering something like:

<AuthorizeView>
    <Authorized>
        <p>You are authorized</p>
        Hello @context.User.Identity?.Name!
    </Authorized>
    <NotAuthorized>
        <p>You are not authorized</p>
    </NotAuthorized>
</AuthorizeView>

This was caused by the PersistentAuthenticationStateProvider on the client attempting to read the UserInfo from PersistentComponentState after enhanced navigation. At this point the state from the original page load (/counter in the examples below) is cleared, and the state that was persisted during the enhanced navigation to /auth is simply ignored and never read by anyone despite calling the RegisterOnPersisting callback and rendering the state for each enhanced navigation. The PersistentComponentState behavior is by design according to @javiercn, and we can make auth work reliably with the current PersistentComponentState behavior by greedily reading the UserInfo during initial render before any enhanced navigation which is what this PR does.

Fixes #51368

Customer Impact

This was thankfully reported by a customer trying out the new Identity Blazor components in RC2. It's possible to get into this state with just the template code if a browser session starts in (or reload on) the template's /counter page and then does enhanced navigation to a component that uses an <AuthorizeView> like the template's /auth page. Without this fix, the user is forced to refresh the /auth page or any other page with <AuthorizeView> before they can see any rendered content that requires authorization.

auth-persistent-state-bug-refresh.mp4

Notice how the second time I navigate to the "Auth Required" page after refreshing on the "Counter" page, you see "You are authenticated" followed by "You are not authorized" even though any authenticated user should be authorized to see that page. After the fix, you always see "You are authenticated" followed by "You are authorized" and "Hello {email}!" as expected.

auth-persistent-state-fix.mp4

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

This is a small change to a single Blazor Identity template component added in RC 2 which slightly simplifies the logic.

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

@ghost ghost added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Oct 19, 2023
@ghost ghost added this to the 8.0.x milestone Oct 19, 2023
@ghost
Copy link

ghost commented Oct 19, 2023

Hi @halter73. If this is not a tell-mode PR, please make sure to follow the instructions laid out in the servicing process document.
Otherwise, please add tell-mode label.

@javiercn
Copy link
Member

PersistentComponentState does not live past the first enhanced navigation during interactive WebAssembly rendering. This is true even if the state is persisted for both the page being navigated to and from, and appears to be due to some sort of bug in PersistentComponentState, but we can work around the issue by always reading the persisted state in the PersistentAuthenticationStateProvider before any enhanced navigation occurs.

PersistentComponentState is only available during the first render by design. It's available only when a given runtime starts.

@halter73 halter73 marked this pull request as ready for review October 19, 2023 18:52
@mkArtakMSFT mkArtakMSFT added area-blazor Includes: Blazor, Razor Components Servicing-consider Shiproom approval is required for the issue and removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Oct 19, 2023
@ghost
Copy link

ghost commented Oct 19, 2023

Hi @halter73. Please make sure you've updated the PR description to use the Shiproom Template. Also, make sure this PR is not marked as a draft and is ready-to-merge.

To learn more about how to prepare a servicing PR click here.

@mkArtakMSFT mkArtakMSFT added Servicing-approved Shiproom has approved the issue and removed Servicing-consider Shiproom approval is required for the issue labels Oct 19, 2023
@ghost
Copy link

ghost commented Oct 19, 2023

Hi @halter73. This PR was just approved to be included in the upcoming servicing release. Somebody from the @dotnet/aspnet-build team will get it merged when the branches are open. Until then, please make sure all the CI checks pass and the PR is reviewed.

@mkArtakMSFT mkArtakMSFT modified the milestones: 8.0.x, 8.0.0 Oct 20, 2023
@mkArtakMSFT mkArtakMSFT merged commit e4ba445 into release/8.0 Oct 20, 2023
@mkArtakMSFT mkArtakMSFT deleted the halter73/51368 branch October 20, 2023 02:58
@ghost ghost added this to the 8.0.0 milestone Oct 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components Servicing-approved Shiproom has approved the issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants