Skip to content
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

Build in AuthenticationStateProviders from project templates #55821

Merged
merged 3 commits into from
May 22, 2024

Conversation

halter73
Copy link
Member

@halter73 halter73 commented May 21, 2024

This automatically registers a client AuthenticationStateProvider's similar to the PersistentAuthenticationStateProvider added by the "Individual Auth" option in the Blazor Web project templates.

This feature must be opted in by calling AddAuthenticationStateSerialization() on the server's IRazorComponentsBuilder and AddAuthenticationStateDeserialization() on the client's IServiceCollection. These methods are defined in Microsoft.AspNetCore.Components.WebAssembly.Server and Microsoft.AspNetCore.Components.WebAssembly.Authentication assemblies respectively, so they should only be available to applications using WebAssembly interactivity.

Even if you do opt-in to authentication state serialization/deserialization, you must further opt-in to serializing all claims by setting AuthenticationStateSerializationOptions.SerializeAllClaims or registering a custom SerializationCallback. Otherwise, only the name and role claims will be serialized.

Rather than override the server's AuthenticationStateProvider like the project template's PersistingServerAuthenticationStateProvider, this registers an AuthenticationStateSerializer which does not implement AuthenticationStateProvider. This allows EndpointHtmlRenderer to flow authentication state from a custom server-side AuthenticationStateProvider to the serializer which is registered directly as IHostEnvironmentAuthenticationStateProvider by AddAuthenticationStateSerialization().

In order to increase the consistency of using AddAuthenticationStateSerialization() with and without server interactivity, ServerAuthenticationStateProvider was type forwarded to Microsoft.AspNetCore.Components.Endpoints and registered by default by AddRazorComponents. This is also helpful for auth in completely non-interactive Blazor web projects.

Fixes #52769

@halter73 halter73 requested a review from a team as a code owner May 21, 2024 16:01
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label May 21, 2024
- Use JSImports instead of DefaultWebAssemblyJSRuntime
- Remove unnecessary exclusions from template.json
- Remove UserInfo from the template client template
- Remove AddAuthorizationCore from AddRazorComponents
Comment on lines +3 to +6
Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider
Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.ServerAuthenticationStateProvider() -> void
Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.SetAuthenticationState(System.Threading.Tasks.Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState!>! authenticationStateTask) -> void
override Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.GetAuthenticationStateAsync() -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState!>!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this public because of layering?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or because we want it to be extendable

Copy link
Member Author

@halter73 halter73 May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mention this in the PR description:

In order to increase the consistency of using AddAuthenticationStateSerialization() with and without server interactivity, ServerAuthenticationStateProvider was type forwarded to Microsoft.AspNetCore.Components.Endpoints and registered by default by AddRazorComponents. This is also helpful for auth in completely non-interactive Blazor web projects.

This change isn't strictly necessary for this PR, but I do think it helps with the general usability AddRazorComponents without AddInteractiveServerComponents. I could have used an internal AuthenticationStateProvider that's functionally equivalent to the ServerAuthenticationStateProvider without the type forwarding to achieve the same thing, but I figured we might as well reduce duplication.

Comment on lines +2 to +5
*REMOVED*Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider
*REMOVED*Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.ServerAuthenticationStateProvider() -> void
*REMOVED*Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.SetAuthenticationState(System.Threading.Tasks.Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState!>! authenticationStateTask) -> void
*REMOVED*override Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.GetAuthenticationStateAsync() -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState!>!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this breaking? (For libraries for example).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider))] should make it non-breaking.

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some more comments, but I don't want to block on them. I'll chat with you offline

@halter73 halter73 merged commit 5f792ae into main May 22, 2024
26 checks passed
@halter73 halter73 deleted the halter73/52769 branch May 22, 2024 21:52
@dotnet-policy-service dotnet-policy-service bot added this to the 9.0-preview5 milestone May 22, 2024
Comment on lines +8 to +10
/// If this is implemented by the host's <see cref="AuthenticationStateProvider"/>, it will receive authentication state from the HttpContext.
/// Or if this implemented service that is registered directly as an <see cref="IHostEnvironmentAuthenticationStateProvider"/>,
/// it will receive the <see cref="AuthenticationState"/> returned by <see cref="AuthenticationStateProvider.GetAuthenticationStateAsync"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// If this is implemented by the host's <see cref="AuthenticationStateProvider"/>, it will receive authentication state from the HttpContext.
/// Or if this implemented service that is registered directly as an <see cref="IHostEnvironmentAuthenticationStateProvider"/>,
/// it will receive the <see cref="AuthenticationState"/> returned by <see cref="AuthenticationStateProvider.GetAuthenticationStateAsync"/>
/// If this is implemented by the host's <see cref="AuthenticationStateProvider"/>, it receives authentication state from the HttpContext.
/// If this implemented service that is registered directly as an <see cref="IHostEnvironmentAuthenticationStateProvider"/>,
/// it receives the <see cref="AuthenticationState"/> returned by <see cref="AuthenticationStateProvider.GetAuthenticationStateAsync"/>

namespace Microsoft.AspNetCore.Components.WebAssembly.Server;

/// <summary>
/// Provides options for configuring the JSON serialization of the <see cref="AuthenticationState"/> provided by the server's <see cref="AuthenticationStateProvider"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to reject this but the sentence is too long and difficult to machine translate.

Suggested change
/// Provides options for configuring the JSON serialization of the <see cref="AuthenticationState"/> provided by the server's <see cref="AuthenticationStateProvider"/>
/// Provides options for configuring the JSON serialization of the <see cref="AuthenticationState"/>. Provided by the server's <see cref="AuthenticationStateProvider"/>

}

/// <summary>
/// If <see langword="true"/>, the default <see cref="SerializationCallback"/> will serialize all claims; otherwise, it will only serialize
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// If <see langword="true"/>, the default <see cref="SerializationCallback"/> will serialize all claims; otherwise, it will only serialize
/// If <see langword="true"/>, the default <see cref="SerializationCallback"/> serializes all claims; otherwise, it only serializes

Comment on lines +31 to +32
/// Default implementation for converting the server's <see cref="AuthenticationState"/> to an <see cref="AuthenticationStateData"/> object
/// for JSON serialization to the client using <see cref="PersistentComponentState"/>."/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Default implementation for converting the server's <see cref="AuthenticationState"/> to an <see cref="AuthenticationStateData"/> object
/// for JSON serialization to the client using <see cref="PersistentComponentState"/>."/>
/// Default implementation for converting the server's <see cref="AuthenticationState"/> to an <see cref="AuthenticationStateData"/> object.
/// This conversion is intended for JSON serialization to the client using <see cref="PersistentComponentState"/>."/>

Comment on lines +36 to +38
/// Serializes the <see cref="AuthenticationState"/> returned by the server-side <see cref="AuthenticationStateProvider"/> using <see cref="PersistentComponentState"/>
/// for use by interactive WebAssembly components via a deserializing client-side <see cref="AuthenticationStateProvider"/> which can be added by calling
/// AddAuthenticationStateDeserialization from the Microsoft.AspNetCore.Components.WebAssembly.Authentication package in the client project.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Serializes the <see cref="AuthenticationState"/> returned by the server-side <see cref="AuthenticationStateProvider"/> using <see cref="PersistentComponentState"/>
/// for use by interactive WebAssembly components via a deserializing client-side <see cref="AuthenticationStateProvider"/> which can be added by calling
/// AddAuthenticationStateDeserialization from the Microsoft.AspNetCore.Components.WebAssembly.Authentication package in the client project.
/// Serializes the <see cref="AuthenticationState"/> returned by the server-side <see cref="AuthenticationStateProvider"/> using <see cref="PersistentComponentState"/>.
/// Intended for use by interactive WebAssembly components via a deserializing client-side <see cref="AuthenticationStateProvider"/>. The WebAssembly can be added by calling
/// AddAuthenticationStateDeserialization from the Microsoft.AspNetCore.Components.WebAssembly.Authentication package in the client project.

Comment on lines +19 to +20
/// Default implementation for converting the <see cref="AuthenticationStateData"/> that was JSON deserialized from the server
/// using <see cref="PersistentComponentState"/> to an <see cref="AuthenticationState"/> object to be returned by the WebAssembly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Default implementation for converting the <see cref="AuthenticationStateData"/> that was JSON deserialized from the server
/// using <see cref="PersistentComponentState"/> to an <see cref="AuthenticationState"/> object to be returned by the WebAssembly
/// Default implementation for converting the <see cref="AuthenticationStateData"/> that was JSON deserialized from the server.
/// This conversion is performed using <see cref="PersistentComponentState"/> to an <see cref="AuthenticationState"/> object.
// This object is then returned by the WebAssembly client's <see

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tdykstra why no rich diff?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, but your new line 21 is missing one slash at the start.

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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Build in AuthenticationStateProviders from Blazor Web templates
4 participants