Cloudstrap.BlazorServer
0.2.0-preview.83
Prefix Reserved
dotnet add package Cloudstrap.BlazorServer --version 0.2.0-preview.83
NuGet\Install-Package Cloudstrap.BlazorServer -Version 0.2.0-preview.83
<PackageReference Include="Cloudstrap.BlazorServer" Version="0.2.0-preview.83" />
<PackageVersion Include="Cloudstrap.BlazorServer" Version="0.2.0-preview.83" />
<PackageReference Include="Cloudstrap.BlazorServer" />
paket add Cloudstrap.BlazorServer --version 0.2.0-preview.83
#r "nuget: Cloudstrap.BlazorServer, 0.2.0-preview.83"
#:package Cloudstrap.BlazorServer@0.2.0-preview.83
#addin nuget:?package=Cloudstrap.BlazorServer&version=0.2.0-preview.83&prerelease
#tool nuget:?package=Cloudstrap.BlazorServer&version=0.2.0-preview.83&prerelease
Cloudstrap.BlazorServer
Blazor Server bootstrap for ASP.NET Core, in two calls: AddCloudstrapBlazorServer() registers the
service side — razor components with the interactivity decided once, hardened antiforgery, HSTS,
correlation, health checks — and UseCloudstrapBlazorServer<App>() builds the request pipeline in
the fixed order a hardened, observable Blazor Server application needs. Circuit-originated work
becomes visible through IBlazorInteractionTrace, a one-method scope that starts a fresh root trace
per user interaction.
The package depends on Cloudstrap.Extensions only (bringing Cloudstrap.Core and
Cloudstrap.Observability transitively). It registers no authentication and no observability
pipeline — both are separate, deliberately visible calls.
Quick start
using Cloudstrap.BlazorServer;
var builder = WebApplication.CreateBuilder(args);
builder.UseCloudstrapObservability(); // separate, visible call
builder.AddCloudstrapBlazorServer(); // core, correlation, probes, razor components,
// hardened antiforgery, HSTS, IBlazorInteractionTrace
builder.Services.AddCloudstrapOpenIdConnect(); // auth pairing is a separate, visible call
builder.Services.AddCloudstrapHttpServiceClient<IDemoApiClient, DemoApiClient>("DemoApi");
WebApplication app = builder.Build();
app.UseCloudstrapBlazorServer<App>(pipeline =>
pipeline.ConfigureEndpoints = endpoints => endpoints.MapCloudstrapAuthenticationEndpoints());
await app.RunAsync();
The pipeline order
UseCloudstrapBlazorServer<TRoot> builds this order, and the order is the point of the call:
- Error handling head — the developer exception page where selected, otherwise
UseExceptionHandlerre-executingCloudstrap:Application:ExceptionHandlerPathwith a fresh scope - HSTS — when enabled and outside
Development - Security headers (set-if-absent)
UsePathBase— whenCloudstrap:Application:PathBaseis configuredBeforeRoutinghook- Routing
- Correlation — before auth, so a
401is as traceable as a200 - Authentication — only when a scheme is registered
BeforeAuthorizationhook- Authorization — under the same condition
- Antiforgery
BeforeEndpointshook- Static-asset endpoints — when
MapStaticAssetsis on (default) - Razor component endpoints for
TRoot— Interactive Server render mode when selected,AdditionalAssemblies, thenConfigureComponentEndpointslast - Health probes (
/healthz,/ready, anonymous) ConfigureEndpointshook
A second Use call throws; a Use call without the matching Add throws, naming the missing call.
Settings — Cloudstrap:BlazorServer
The section is optional; every default applies without it. Validated at startup, naming the offending key.
| Key | Default | Meaning |
|---|---|---|
Hsts:Enabled |
true |
Emit Strict-Transport-Security outside Development |
Hsts:MaxAgeDays |
365 |
HSTS max age (must be ≥ 1) |
Hsts:IncludeSubDomains |
true |
HSTS includeSubDomains directive |
Hsts:Preload |
false |
HSTS preload directive |
ExceptionHandling:UseDeveloperExceptionPage |
environment | true/false overrides the Development default |
EnableFrameOptions |
true |
Emit X-Frame-Options: SAMEORIGIN (set false if the app must be framed) |
Code-level overrides
AddCloudstrapBlazorServer(configurator => ...):
| Hook | Default | Meaning |
|---|---|---|
Interactivity |
InteractiveServer |
StaticServer skips all interactive wiring — decided once, here; the pipeline call follows it |
Antiforgery |
hardened cookie (HttpOnly, SecurePolicy=Always, SameSite=Strict) |
Runs last over the hardened defaults — final say |
RazorComponents |
— | Runs last against the IRazorComponentsBuilder (e.g. CircuitOptions, adding a WASM render mode) |
UseCloudstrapBlazorServer<TRoot>(pipeline => ...):
| Hook | Default | Meaning |
|---|---|---|
MapStaticAssets |
true |
Map the built static-asset endpoints |
AdditionalAssemblies |
empty | Extra assemblies whose routable components join the router |
BeforeRouting / BeforeAuthorization / BeforeEndpoints |
— | Middleware insertion points, in the order named |
ConfigureComponentEndpoints |
— | Runs last on the component convention builder |
ConfigureEndpoints |
— | Your own endpoints (auth endpoints, minimal APIs), mapped after the probes |
Security headers
Set-if-absent on every response — a header the application already set is never overwritten:
X-Content-Type-Options: nosniffReferrer-Policy: no-referrerX-Frame-Options: SAMEORIGIN— omitted whenEnableFrameOptionsisfalse
Interaction tracing — IBlazorInteractionTrace
Cloudstrap's observability package drops the noisy SignalR hub trace a circuit runs under — so work started in a circuit event handler would vanish with it. Wrap the interaction instead:
public sealed class CheckoutViewModel(IDemoApiClient api, IBlazorInteractionTrace trace)
{
public async Task SubmitAsync()
{
using (trace.StartInteraction("checkout"))
{
await api.SubmitOrderAsync(); // parented under the interaction root,
} // correlated with its trace id
}
}
StartInteraction starts a root activity detached from the ambient hub trace, points the ambient
correlation identifier at the new trace id (outbound HTTP calls carry it), and restores both on
dispose. Without a trace listener it is a safe no-op that still sets a fresh correlation identifier.
The activity source, BlazorServerActivitySources.Interaction
("Cloudstrap.BlazorServer.Interaction"), is contributed additively to any OpenTelemetry pipeline
built from the application's service collection — Cloudstrap's owner or contribute mode, or an
Aspire-style host's own. The package creates no pipeline and no exporter of its own; a pipeline
owner outside DI can AddSource the published constant themselves.
Recipes
- Multi-instance deployments need shared data-protection keys (antiforgery and auth cookies):
call
AddCloudstrapDataProtectionfromCloudstrap.Extensions. - Richer security headers (CSP and friends): add the
NetEscapades.AspNetCore.SecurityHeadersmiddleware inBeforeRouting— the package's own headers never overwrite yours. - Interactive WebAssembly render modes: reference the WASM server package yourself, add the
services via
configurator.RazorComponents, and the render mode viaConfigureComponentEndpoints— the composite stays Server-only by design. - Behind a proxy: forwarded headers are deliberately not configured here — set the platform's
ASPNETCORE_FORWARDEDHEADERS_ENABLED=trueor place the middleware inBeforeRouting.
Aspire coexistence
No Aspire.* reference. Health checks register on the stock IHealthChecksBuilder, the interaction
source contributes to an existing DI-built tracer pipeline without duplicating exporters, and typed
HttpClients come from Cloudstrap.Extensions unchanged — tolerant of resilience handlers applied
via ConfigureHttpClientDefaults.
Migrating from the enterprise predecessor
AddBlazorForNihdi/UseBlazorForNihdi→AddCloudstrapBlazorServer/UseCloudstrapBlazorServer<TRoot>; the render-mode knob exists once, at registration time./probeand/probe.aspx→/healthz+/ready(anonymous, additive on the stock builder).- Antiforgery cookie is hardened by default; the configurator hook has the final say.
- Auth middleware appears exactly when a scheme is registered — after routing, before antiforgery;
no forced
RequireAuthorization, no built-in controllers. - Path base comes from
Cloudstrap:Application:PathBaseonly — no environment-variable sniffing. - Forwarded headers, HTTPS redirection and CORS wiring are gone — platform conventions instead.
- WASM reflection probing is gone — reference and wire WASM render modes explicitly.
- KeyVault data protection, localization and Scalar auto-wiring are separate, visible calls.
IDistributedTraceServiceand its 1–5 generic overloads →IBlazorInteractionTrace, one method; the automaticActivitySourceDelegatingHandleris gone — outbound tracing belongs to the OpenTelemetry HTTP instrumentation.- Obsolete legacy methods were not carried over.
X-Frame-Options: SAMEORIGINis emitted by default —EnableFrameOptions=falseturns it off.- No
Cloudstrap.BlazorCommondependency — adopt the ViewModel convention at application level.
License
MIT — part of the Cloudstrap suite.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AspNetCore.HealthChecks.Uris (>= 9.0.0)
- Azure.Extensions.AspNetCore.Configuration.Secrets (>= 1.5.1)
- Azure.Extensions.AspNetCore.DataProtection.Blobs (>= 1.5.3)
- Azure.Extensions.AspNetCore.DataProtection.Keys (>= 1.6.3)
- Azure.Identity (>= 1.21.0)
- Azure.Storage.Blobs (>= 12.29.1)
- Cloudstrap.Extensions (>= 0.2.0-preview.83)
- OpenTelemetry.Exporter.Console (>= 1.17.0)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.17.0)
- OpenTelemetry.Extensions.Hosting (>= 1.17.0)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.17.0)
- OpenTelemetry.Instrumentation.Http (>= 1.17.0)
- OpenTelemetry.Instrumentation.Runtime (>= 1.17.0)
- OpenTelemetry.Instrumentation.SqlClient (>= 1.17.0)
- Serilog (>= 4.4.0)
- Serilog.Extensions.Hosting (>= 10.0.0)
- Serilog.Sinks.Console (>= 6.1.1)
- Serilog.Sinks.File (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.2.0-preview.83 | 33 | 9/3/2026 |
| 0.2.0-preview.2 | 64 | 8/27/2026 |