Blazor Server support
PREREQUISITES: This feature is available only for projects provisioned on the unified Sitefinity Cloud infrastructure. If your project was provisioned before May 2025, contact the Sitefinity Cloud team to verify eligibility.
Overview
Sitefinity Cloud supports Blazor Server components in ASP.NET Core Renderer applications running on multi-pod Azure Kubernetes Service (AKS) deployments.
NOTE: A multi-pod AKS deployment means your Renderer application is scaled out to run as multiple parallel instances on Azure Kubernetes (for redundancy and load distribution).
In multi-pod AKS deployments, Blazor Server requires shared SignalR state and consistent Data Protection keys across all pods.
Sitefinity Cloud manages the required Azure infrastructure automatically, so your ASP.NET Core Renderer runs reliably once you have configured and updated it as described below.
How it works
When Blazor Server support is enabled for your project, the following Azure infrastructure is provisioned automatically:
| Resource | Purpose |
|---|---|
| Azure SignalR Service | Managed SignalR hub that routes connections to the correct pod |
| User-assigned managed identity | Authenticates the Renderer pods to Azure Blob Storage and Azure Key Vault through Microsoft Entra Workload ID |
| Azure Key Vault encryption key | Encrypts Data Protection keys at rest |
| Blob container | Stores the shared Data Protection keys.xml file |
All pods in your Renderer deployment connect to the Azure SignalR Service, which ensures that Blazor circuits maintain their state regardless of which pod handles the reconnection. Data Protection keys are stored centrally in Azure Blob Storage and encrypted with a Key Vault key, so all pods can encrypt and decrypt antiforgery tokens and authentication cookies consistently.
Authentication from the pod to Azure resources happens through Workload ID for Blob Storage and Key Vault access. The CI/CD pipeline injects the Azure SignalR connection string as an environment variable during deployment. The pod obtains an Azure token automatically through a projected Kubernetes service account token.
Request the feature
To request Blazor Server support for your project:
- Log a support case.
- Describe the desired goal.
The Sitefinity Cloud team will set up the required Azure infrastructure and update your CI/CD pipeline.
You must configure and update your ASP.NET Core Renderer to use the provisioned infrastructure, as described in the following sections.
Configure your ASP.NET Core Renderer
Add NuGet packages
Add the following package references to the .csproj file of your Renderer:
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" />
<PackageReference Include="Microsoft.Azure.SignalR" />
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" />
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Keys" />
<PackageReference Include="Azure.Identity" />
If you use Central Package Management, add the versions to your Directory.Packages.props file:
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.14" />
<PackageVersion Include="Microsoft.Azure.SignalR" Version="1.33.0" />
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.4" />
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Keys" Version="1.2.4" />
<PackageVersion Include="Azure.Identity" Version="1.13.2" />
NOTE: Use the latest stable versions available at the time of implementation. The versions mentioned above are the minimum verified versions.
Configure Data Protection with Workload ID
Add the following code to your Program.cs file before AddServerSideBlazor():
using System;
using Microsoft.AspNetCore.DataProtection;
using Azure.Identity;
// After builder.Services.AddSitefinity() and other service registrations
var dpBlobUri = builder.Configuration["Sitefinity:DataProtection:Azure:BlobUri"];
var dpKeyUri = builder.Configuration["Sitefinity:DataProtection:Azure:KeyUri"];
if (!string.IsNullOrEmpty(dpBlobUri) && !string.IsNullOrEmpty(dpKeyUri))
{
var credential = new DefaultAzureCredential();
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(new Uri(dpBlobUri), credential)
.ProtectKeysWithAzureKeyVault(new Uri(dpKeyUri), credential);
}
This code reads the blob URI and Key Vault key URI from environment variables that the CI/CD pipeline injects automatically. It uses DefaultAzureCredential, which automatically picks up Workload ID in AKS.
When the environment variables are not set, as in a local development environment, the Data Protection configuration is skipped.
Configure Azure SignalR Service
Add SignalR and Blazor Services to your Program.cs file. The Content Security Policy (CSP) delegate is required so that the browser can establish WebSocket connections to the SignalR endpoint:
var signalREndpoint = builder.Configuration["Azure:SignalR:Endpoint"] ?? string.Empty;
builder.Services.AddSitefinity(x =>
{
x.CspOptions.CspDelegate = (csp, context) =>
{
if (!string.IsNullOrEmpty(signalREndpoint))
{
var wsEndpoint = signalREndpoint.Replace("https://", "wss://");
csp.ConnectSrc = $"{signalREndpoint} {wsEndpoint} " + csp.ConnectSrc;
}
};
});
builder.Services.AddServerSideBlazor();
builder.Services.AddSignalR()
.AddAzureSignalR(options =>
{
options.ServerStickyMode = Microsoft.Azure.SignalR.ServerStickyMode.Required;
options.ConnectionString = builder.Configuration["Azure:SignalR:ConnectionString"];
});
NOTE: The
ServerStickyMode.Requiredsetting ensures that Blazor circuits are always routed back to the same application server, which is essential for maintaining circuit state.
Map the Blazor hub
At the end of the middleware pipeline, after app.UseSitefinity(), add the following:
app.MapBlazorHub();
Deploy the Renderer
After you update your Renderer code, run the DotNetCoreRenderer.CI.CD pipeline. The pipeline automatically reads the SignalR and Data Protection settings from Key Vault and injects them as environment variables during deployment. No manual configuration of connection strings or keys is required.
Verify the setup
After deployment, you can verify that Blazor Server is working correctly by:
- Opening a page that contains Blazor components.
- Verifying that the Blazor components render and respond to user interactions.
- Checking the browser developer tools network tab for WebSocket connections to the Azure SignalR Service endpoint.
If Blazor components fail intermittently, verify the following:
- The
Azure:SignalR:ConnectionStringenvironment variable is set on the pod. - The Data Protection
keys.xmlfile exists in the blob storage container. - The
ServerStickyModeis set toRequiredin your code.
Troubleshooting
Blazor components show "The list of component records is not valid"
This error occurs when a SignalR reconnection reaches a different pod that does not have the circuit state. Verify that:
- Azure SignalR Service is properly configured for your project
- The
Azure:SignalR:ConnectionStringenvironment variable is present in the pod ServerStickyModeis set toRequiredin yourProgram.cscode
Antiforgery token validation fails across pods
This issue occurs when Data Protection keys are not shared between pods. Verify that:
- The
Sitefinity:DataProtection:Azure:BlobUrienvironment variable is set - The
Sitefinity:DataProtection:Azure:KeyUrienvironment variable is set - The Data Protection
keys.xmlfile exists and is encrypted (containsAzureKeyVaultXmlDecryptorin its content)
If the keys.xml file contains an unencrypted key, it means the pod started before the Key Vault encryption key was provisioned. Contact the Sitefinity Cloud team to resolve this issue.
Pod cannot authenticate to Azure resources
If pod logs show Azure.Identity.CredentialUnavailableException, this indicates that Workload Identity is not configured correctly. Contact the Sitefinity Cloud team to verify the service account annotations and federated identity credentials.