Skip to content

Commit d89743b

Browse files
committed
Make DefaultAntiforgeryStateProvider shared source
1 parent 0ed7919 commit d89743b

16 files changed

+57
-48
lines changed

src/Components/Endpoints/src/DependencyInjection/RazorComponentsServiceCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public static IRazorComponentsBuilder AddRazorComponents(this IServiceCollection
6464
services.TryAddScoped<IFormValueSupplier, DefaultFormValuesSupplier>();
6565
services.TryAddEnumerable(ServiceDescriptor.Scoped<CascadingModelBindingProvider, CascadingQueryModelBindingProvider>());
6666
services.TryAddEnumerable(ServiceDescriptor.Scoped<CascadingModelBindingProvider, CascadingFormModelBindingProvider>());
67-
services.TryAddScoped<AntiforgeryStateProvider, EndpointAntiforgeryStateProvider>();
67+
services.TryAddScoped<DefaultAntiforgeryStateProvider, EndpointAntiforgeryStateProvider>();
6868
return new DefaultRazorComponentsBuilder(services);
6969
}
7070

src/Components/Endpoints/src/Forms/EndpointAntiforgeryStateProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Microsoft.AspNetCore.Components.Endpoints.Forms;
99

10-
internal class EndpointAntiforgeryStateProvider(IAntiforgery antiforgery, PersistentComponentState state) : AntiforgeryStateProvider(state)
10+
internal class EndpointAntiforgeryStateProvider(IAntiforgery antiforgery, PersistentComponentState state) : DefaultAntiforgeryStateProvider(state)
1111
{
1212
private HttpContext? _context;
1313

src/Components/Endpoints/src/Microsoft.AspNetCore.Components.Endpoints.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<Compile Include="$(RepoRoot)src\Shared\Components\ProtectedPrerenderComponentApplicationStore.cs" LinkBase="DependencyInjection" />
3636
<Compile Include="$(RepoRoot)src\Shared\ClosedGenericMatcher\ClosedGenericMatcher.cs" LinkBase="Binding" />
3737
<Compile Include="$(ComponentsSharedSourceRoot)src\CacheHeaderSettings.cs" Link="Shared\CacheHeaderSettings.cs" />
38+
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultAntiforgeryStateProvider.cs" LinkBase="Forms" />
3839

3940
<Compile Include="$(SharedSourceRoot)PropertyHelper\**\*.cs" />
4041

src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ internal static async Task InitializeStandardComponentServicesAsync(
8989
formData.SetFormData(handler, new FormCollectionReadOnlyDictionary(form));
9090
}
9191

92-
if (httpContext.RequestServices.GetService<AntiforgeryStateProvider>() is EndpointAntiforgeryStateProvider antiforgery)
92+
if (httpContext.RequestServices.GetService<DefaultAntiforgeryStateProvider>() is EndpointAntiforgeryStateProvider antiforgery)
9393
{
9494
antiforgery.SetRequestContext(httpContext);
9595
}

src/Components/Endpoints/test/EndpointHtmlRendererTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,7 @@ private static ServiceCollection CreateDefaultServiceCollection()
13011301
services.AddAntiforgery();
13021302
services.AddSingleton<ComponentStatePersistenceManager>();
13031303
services.AddSingleton<PersistentComponentState>(sp => sp.GetRequiredService<ComponentStatePersistenceManager>().State);
1304-
services.AddSingleton<AntiforgeryStateProvider, EndpointAntiforgeryStateProvider>();
1304+
services.AddSingleton<DefaultAntiforgeryStateProvider, EndpointAntiforgeryStateProvider>();
13051305

13061306
return services;
13071307
}

src/Components/Endpoints/test/RazorComponentResultExecutorTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ public static DefaultHttpContext GetTestHttpContext(string environmentName = nul
417417
.AddSingleton<FormDataProvider, HttpContextFormDataProvider>()
418418
.AddSingleton<ComponentStatePersistenceManager>()
419419
.AddSingleton<PersistentComponentState>(sp => sp.GetRequiredService<ComponentStatePersistenceManager>().State)
420-
.AddSingleton<AntiforgeryStateProvider, EndpointAntiforgeryStateProvider>()
420+
.AddSingleton<DefaultAntiforgeryStateProvider, EndpointAntiforgeryStateProvider>()
421421
.AddLogging();
422422

423423
var result = new DefaultHttpContext { RequestServices = serviceCollection.BuildServiceProvider() };

src/Components/Server/src/DependencyInjection/ComponentServiceCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static IServerSideBlazorBuilder AddServerSideBlazor(this IServiceCollecti
6969
services.TryAddSingleton<ComponentParametersTypeCache>();
7070
services.TryAddSingleton<CircuitIdFactory>();
7171
services.TryAddScoped<IErrorBoundaryLogger, RemoteErrorBoundaryLogger>();
72-
services.TryAddScoped<AntiforgeryStateProvider>();
72+
services.TryAddScoped<AntiforgeryStateProvider, DefaultAntiforgeryStateProvider>();
7373

7474
services.TryAddScoped(s => s.GetRequiredService<ICircuitAccessor>().Circuit);
7575
services.TryAddScoped<ICircuitAccessor, DefaultCircuitAccessor>();

src/Components/Server/src/Microsoft.AspNetCore.Components.Server.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
<Compile Include="$(ComponentsSharedSourceRoot)src\ElementReferenceJsonConverter.cs" />
6565
<Compile Include="$(ComponentsSharedSourceRoot)src\ComponentParametersTypeCache.cs" />
6666
<Compile Include="$(ComponentsSharedSourceRoot)src\RootComponentTypeCache.cs" />
67+
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultAntiforgeryStateProvider.cs" LinkBase="Forms" />
6768

6869
<Compile Include="..\..\Shared\src\BrowserNavigationManagerInterop.cs" />
6970
<Compile Include="..\..\Shared\src\JsonSerializerOptionsProvider.cs" />
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Diagnostics.CodeAnalysis;
5+
6+
namespace Microsoft.AspNetCore.Components.Forms;
7+
8+
internal class DefaultAntiforgeryStateProvider : AntiforgeryStateProvider, IDisposable
9+
{
10+
private const string PersistenceKey = $"__internal__{nameof(AntiforgeryRequestToken)}";
11+
private readonly PersistingComponentStateSubscription _subscription;
12+
private readonly AntiforgeryRequestToken? _currentToken;
13+
14+
[UnconditionalSuppressMessage(
15+
"Trimming",
16+
"IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code",
17+
Justification = $"{nameof(DefaultAntiforgeryStateProvider)} uses the {nameof(PersistentComponentState)} APIs to deserialize the token, which are already annotated.")]
18+
public DefaultAntiforgeryStateProvider(PersistentComponentState state)
19+
{
20+
// Automatically flow the Request token to server/wasm through
21+
// persistent component state. This guarantees that the antiforgery
22+
// token is available on the interactive components, even when they
23+
// don't have access to the request.
24+
_subscription = state.RegisterOnPersisting(() =>
25+
{
26+
state.PersistAsJson(PersistenceKey, _currentToken);
27+
return Task.CompletedTask;
28+
});
29+
30+
state.TryTakeFromJson(PersistenceKey, out _currentToken);
31+
}
32+
33+
/// <inheritdoc />
34+
public override AntiforgeryRequestToken? GetAntiforgeryToken() => _currentToken;
35+
36+
/// <inheritdoc />
37+
public void Dispose() => _subscription.Dispose();
38+
}
Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,16 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Diagnostics.CodeAnalysis;
5-
64
namespace Microsoft.AspNetCore.Components.Forms;
75

86
/// <summary>
97
/// Provides access to the antiforgery token associated with the current session.
108
/// </summary>
11-
public class AntiforgeryStateProvider : IDisposable
9+
public abstract class AntiforgeryStateProvider
1210
{
13-
private const string PersistenceKey = $"__internal__{nameof(AntiforgeryRequestToken)}";
14-
private readonly PersistingComponentStateSubscription _subscription;
15-
private readonly AntiforgeryRequestToken? _currentToken;
16-
17-
/// <summary>
18-
/// Initializes a new instance of <see cref="AntiforgeryStateProvider"/>.
19-
/// </summary>
20-
/// <param name="state">The <see cref="PersistentComponentState"/> associated with the current session.</param>
21-
[UnconditionalSuppressMessage(
22-
"Trimming",
23-
"IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code",
24-
Justification = $"{nameof(AntiforgeryStateProvider)} uses the {nameof(PersistentComponentState)} APIs to deserialize the token, which are already annotated.")]
25-
public AntiforgeryStateProvider(PersistentComponentState state)
26-
{
27-
// Automatically flow the Request token to server/wasm through
28-
// persistent component state. This guarantees that the antiforgery
29-
// token is available on the interactive components, even when they
30-
// don't have access to the request.
31-
_subscription = state.RegisterOnPersisting(() =>
32-
{
33-
state.PersistAsJson(PersistenceKey, _currentToken);
34-
return Task.CompletedTask;
35-
});
36-
37-
state.TryTakeFromJson(PersistenceKey, out _currentToken);
38-
}
39-
4011
/// <summary>
4112
/// Gets the current <see cref="AntiforgeryRequestToken"/> if available.
4213
/// </summary>
4314
/// <returns>The current <see cref="AntiforgeryRequestToken"/> if available.</returns>
44-
public virtual AntiforgeryRequestToken? GetAntiforgeryToken() => _currentToken;
45-
46-
/// <inheritdoc />
47-
public void Dispose() => _subscription.Dispose();
15+
public abstract AntiforgeryRequestToken? GetAntiforgeryToken();
4816
}

src/Components/Web/src/Microsoft.AspNetCore.Components.Web.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
<ItemGroup>
1616
<Compile Include="$(ComponentsSharedSourceRoot)src\ExpressionFormatting\**\*.cs" LinkBase="Forms\ExpressionFommatting" />
17+
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultAntiforgeryStateProvider.cs" LinkBase="Forms" />
1718
</ItemGroup>
1819

1920
<ItemGroup>

src/Components/Web/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22
*REMOVED*override Microsoft.AspNetCore.Components.Forms.InputFile.OnInitialized() -> void
3+
abstract Microsoft.AspNetCore.Components.Forms.AntiforgeryStateProvider.GetAntiforgeryToken() -> Microsoft.AspNetCore.Components.Forms.AntiforgeryRequestToken?
34
abstract Microsoft.AspNetCore.Components.Forms.FormDataProvider.Entries.get -> System.Collections.Generic.IReadOnlyDictionary<string!, Microsoft.Extensions.Primitives.StringValues>!
45
abstract Microsoft.AspNetCore.Components.Forms.FormDataProvider.Name.get -> string?
56
Microsoft.AspNetCore.Components.Binding.CascadingFormModelBindingProvider
@@ -9,8 +10,7 @@ Microsoft.AspNetCore.Components.Forms.AntiforgeryRequestToken.AntiforgeryRequest
910
Microsoft.AspNetCore.Components.Forms.AntiforgeryRequestToken.FormFieldName.get -> string!
1011
Microsoft.AspNetCore.Components.Forms.AntiforgeryRequestToken.Value.get -> string!
1112
Microsoft.AspNetCore.Components.Forms.AntiforgeryStateProvider
12-
Microsoft.AspNetCore.Components.Forms.AntiforgeryStateProvider.AntiforgeryStateProvider(Microsoft.AspNetCore.Components.PersistentComponentState! state) -> void
13-
Microsoft.AspNetCore.Components.Forms.AntiforgeryStateProvider.Dispose() -> void
13+
Microsoft.AspNetCore.Components.Forms.AntiforgeryStateProvider.AntiforgeryStateProvider() -> void
1414
Microsoft.AspNetCore.Components.Forms.AntiforgeryToken
1515
Microsoft.AspNetCore.Components.Forms.AntiforgeryToken.AntiforgeryToken() -> void
1616
Microsoft.AspNetCore.Components.Forms.FormDataProvider
@@ -82,5 +82,4 @@ override Microsoft.AspNetCore.Components.Web.RenderModeWebAssemblyAttribute.Mode
8282
static Microsoft.AspNetCore.Components.Web.RenderMode.Auto.get -> Microsoft.AspNetCore.Components.Web.AutoRenderMode!
8383
static Microsoft.AspNetCore.Components.Web.RenderMode.Server.get -> Microsoft.AspNetCore.Components.Web.ServerRenderMode!
8484
static Microsoft.AspNetCore.Components.Web.RenderMode.WebAssembly.get -> Microsoft.AspNetCore.Components.Web.WebAssemblyRenderMode!
85-
virtual Microsoft.AspNetCore.Components.Forms.AntiforgeryStateProvider.GetAntiforgeryToken() -> Microsoft.AspNetCore.Components.Forms.AntiforgeryRequestToken?
8685
virtual Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.WriteComponentHtml(int componentId, System.IO.TextWriter! output) -> void

src/Components/Web/test/Forms/EditFormTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public EditFormTest()
2525
services.AddLogging();
2626
services.AddSingleton<ComponentStatePersistenceManager>();
2727
services.AddSingleton(services => services.GetRequiredService<ComponentStatePersistenceManager>().State);
28-
services.AddSingleton<AntiforgeryStateProvider, AntiforgeryStateProvider>();
28+
services.AddSingleton<AntiforgeryStateProvider, DefaultAntiforgeryStateProvider>();
2929
_testRenderer = new(services.BuildServiceProvider());
3030
}
3131

src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ internal void InitializeDefaultServices()
256256
Services.AddSingleton(new LazyAssemblyLoader(DefaultWebAssemblyJSRuntime.Instance));
257257
Services.AddSingleton<ComponentStatePersistenceManager>();
258258
Services.AddSingleton<PersistentComponentState>(sp => sp.GetRequiredService<ComponentStatePersistenceManager>().State);
259-
Services.AddSingleton<AntiforgeryStateProvider>();
259+
Services.AddSingleton<AntiforgeryStateProvider, DefaultAntiforgeryStateProvider>();
260260
Services.AddSingleton<IErrorBoundaryLogger, WebAssemblyErrorBoundaryLogger>();
261261
Services.AddLogging(builder =>
262262
{

src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<Compile Include="$(SharedSourceRoot)Components\ComponentParameter.cs" Link="Prerendering/ComponentParameter.cs" />
4444
<Compile Include="$(SharedSourceRoot)Components\PrerenderComponentApplicationStore.cs" />
4545
<Compile Include="$(SharedSourceRoot)LinkerFlags.cs" LinkBase="Shared" />
46+
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultAntiforgeryStateProvider.cs" LinkBase="Forms" />
4647
</ItemGroup>
4748

4849
<ItemGroup>

src/ProjectTemplates/Web.ProjectTemplates/content/Components-CSharp/.template.config/localize/templatestrings.en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
1111
"symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.",
1212
"symbols/iisHttpsPort/description": "Port number to use for the IIS Express HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
13-
"symbols/UseWebAssembly/displayName": "_Use interactive webassembly components",
14-
"symbols/UseWebAssembly/description": "If specified, configures the project to render components interactively on the browser using webassembly.",
13+
"symbols/UseWebAssembly/displayName": "_Use interactive WebAssembly components",
14+
"symbols/UseWebAssembly/description": "If specified, configures the project to render components interactively in the browser using WebAssembly.",
1515
"symbols/UseServer/displayName": "_Use interactive server components",
1616
"symbols/UseServer/description": "If specified, configures the project to render components interactively on the server.",
1717
"symbols/PWA/displayName": "_Progressive Web Application",

0 commit comments

Comments
 (0)