title | author | description | monikerRange | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|---|
Secure ASP.NET Core server-side Blazor apps |
guardrex |
Learn how to secure server-side Blazor apps as ASP.NET Core applications. |
>= aspnetcore-3.1 |
riande |
mvc |
02/16/2023 |
blazor/security/server/index |
This article explains how to secure server-side Blazor apps as ASP.NET Core applications.
Server-side Blazor apps are configured for security in the same manner as ASP.NET Core apps. For more information, see the articles under xref:security/index.
The authentication context is only established when the app starts, which is when the app first connects to the WebSocket. The authentication context is maintained for the lifetime of the circuit. Apps periodically revalidate the user's authentication state, currently every 30 minutes by default.
If the app must capture users for custom services or react to updates to the user, see xref:blazor/security/server/additional-scenarios#circuit-handler-to-capture-users-for-custom-services.
Blazor differs from a traditional server-rendered web apps that make new HTTP requests with cookies on every page navigation. Authentication is checked during navigation events. However, cookies aren't involved. Cookies are only sent when making an HTTP request to a server, which isn't what happens when the user navigates in a Blazor app. During navigation, the user's authentication state is checked within the Blazor circuit, which you can update at any time on the server using the RevalidatingAuthenticationStateProvider
abstraction.
Important
Implementing a custom NavigationManager
to achieve authentication validation during navigation isn't recommended. If the app must execute custom authentication state logic during navigation, use a custom AuthenticationStateProvider
.
Note
The code examples in this article adopt nullable reference types (NRTs) and .NET compiler null-state static analysis, which are supported in ASP.NET Core 6.0 or later. When targeting ASP.NET Core 5.0 or earlier, remove the null type designation (?
) from the examples in this article.
Create a new server-side Blazor app by following the guidance in xref:blazor/tooling.
After choosing the server-side app template and configuring the project, select the app's authentication under Authentication type:
:::moniker range=">= aspnetcore-8.0"
- None (default): No authentication.
- Individual Accounts: User accounts are stored within the app using ASP.NET Core Identity.
:::moniker-end
:::moniker range="< aspnetcore-8.0"
- None (default): No authentication.
- Individual Accounts: User accounts are stored within the app using ASP.NET Core Identity.
- Microsoft identity platform: For more information, see xref:blazor/security/index#additional-resources.
- Windows: Use Windows Authentication.
:::moniker-end
When issuing the .NET CLI command to create and configure the server-side Blazor app, indicate the authentication mechanism with the -au|--auth
option:
-au {AUTHENTICATION}
Note
For the full command, see xref:blazor/tooling.
Permissible authentication values for the {AUTHENTICATION}
placeholder are shown in the following table.
:::moniker range=">= aspnetcore-8.0"
Authentication mechanism | Description |
---|---|
None (default) |
No authentication |
Individual |
Users stored in the app with ASP.NET Core Identity |
:::moniker-end
:::moniker range="< aspnetcore-8.0"
Authentication mechanism | Description |
---|---|
None (default) |
No authentication |
Individual |
Users stored in the app with ASP.NET Core Identity |
IndividualB2C |
Users stored in Azure AD B2C |
SingleOrg |
Organizational authentication for a single tenant |
MultiOrg |
Organizational authentication for multiple tenants |
Windows |
Windows Authentication |
:::moniker-end
For more information, see the dotnet new
command in the .NET Core Guide.
When issuing the .NET CLI command to create and configure the server-side Blazor app, indicate the authentication mechanism with the -au|--auth
option:
-au {AUTHENTICATION}
Note
For the full command, see xref:blazor/tooling.
Permissible authentication values for the {AUTHENTICATION}
placeholder are shown in the following table.
:::moniker range=">= aspnetcore-8.0"
Authentication mechanism | Description |
---|---|
None (default) |
No authentication |
Individual |
Users stored in the app with ASP.NET Core Identity |
:::moniker-end
:::moniker range="< aspnetcore-8.0"
Authentication mechanism | Description |
---|---|
None (default) |
No authentication |
Individual |
Users stored in the app with ASP.NET Core Identity |
IndividualB2C |
Users stored in Azure AD B2C |
SingleOrg |
Organizational authentication for a single tenant |
MultiOrg |
Organizational authentication for multiple tenants |
Windows |
Windows Authentication |
:::moniker-end
For more information:
-
See the
dotnet new
command in the .NET Core Guide. -
Execute the help command for the template in a command shell:
dotnet new {PROJECT TEMPLATE} --help
In the preceding command, the
{PROJECT TEMPLATE}
placeholder is the project template.
:::moniker range=">= aspnetcore-8.0"
Blazor supports generating a full Blazor-based Identity UI when you choose the authentication option for Individual Accounts.
The Blazor Web App template scaffolds Identity code for a SQL Server database. The command line version uses SQLite by default and includes a SQLite database for Identity.
The template handles the following:
- Adds Identity Razor components and related logic for routine authentication tasks, such as signing users in and out.
- The Identity components also support advanced Identity features, such as account confirmation and password recovery and multifactor authentication using a third-party app.
- Interactive server and interactive client rendering scenarios are supported.
- Adds the Identity-related packages and dependencies.
- References the Identity packages in
_Imports.razor
. - Creates a custom user Identity class (
ApplicationUser
). - Creates and registers an EF Core database context (
ApplicationDbContext
). - Configures routing for the built-in Identity endpoints.
- Includes Identity validation and business logic.
When you choose the Interactive WebAssembly or Interactive Auto render modes, the server handles all authentication and authorization requests, and the Identity components remain on the server in the Blazor Web App's main project. The project template includes a PersistentAuthenticationStateProvider
class in the .Client
project to synchronize the user's authentication state between the server and the browser. The class is a custom implementation of xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider. The provider uses the xref:Microsoft.AspNetCore.Components.PersistentComponentState class to prerender the authentication state and persist it to the page.
In the main project of a Blazor Web App, the authentication state provider is named either IdentityRevalidatingAuthenticationStateProvider
(Server interactivity solutions only) or PersistingRevalidatingAuthenticationStateProvider
(WebAssembly or Auto interactivity solutions).
For more information on persisting prerendered state, see xref:blazor/components/prerender#persist-prerendered-state.
For more information on the Blazor Identity UI and guidance on integrating external logins through social websites, see What's new with identity in .NET 8.
:::moniker-end
:::moniker range="< aspnetcore-8.0"
:::moniker-end
:::moniker range=">= aspnetcore-6.0 < aspnetcore-8.0"
For more information on scaffolding Identity into a server-side Blazor app, see xref:security/authentication/scaffold-identity#scaffold-identity-into-a-server-side-blazor-app.
:::moniker-end
:::moniker range="< aspnetcore-6.0"
Scaffold Identity into a server-side Blazor app:
- Without existing authorization.
- With authorization.
:::moniker-end
To store additional claims from external providers, see xref:security/authentication/social/additional-claims.
Specify the issuer explicitly when deploying to Azure App Service on Linux with Identity Server. For more information, see xref:security/authentication/identity/spa#azure-app-service-on-linux.
If the app requires a custom provider, implement xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider and override xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider.GetAuthenticationStateAsync%2A.
In the following example, all users are authenticated with the username mrfibuli
.
CustomAuthenticationStateProvider.cs
:
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "mrfibuli"),
}, "Custom Authentication");
var user = new ClaimsPrincipal(identity);
return Task.FromResult(new AuthenticationState(user));
}
}
:::moniker range=">= aspnetcore-6.0"
The CustomAuthenticationStateProvider
service is registered in the Program
file after the call to xref:Microsoft.Extensions.DependencyInjection.ComponentServiceCollectionExtensions.AddServerSideBlazor%2A:
using Microsoft.AspNetCore.Components.Authorization;
...
builder.Services.AddServerSideBlazor();
...
builder.Services.AddScoped<AuthenticationStateProvider,
CustomAuthenticationStateProvider>();
:::moniker-end
:::moniker range="< aspnetcore-6.0"
The CustomAuthenticationStateProvider
service is registered in Startup.ConfigureServices
of Startup.cs
after the call to xref:Microsoft.Extensions.DependencyInjection.ComponentServiceCollectionExtensions.AddServerSideBlazor%2A:
using Microsoft.AspNetCore.Components.Authorization;
...
services.AddServerSideBlazor();
...
services.AddScoped<AuthenticationStateProvider,
CustomAuthenticationStateProvider>();
:::moniker-end
Confirm or add an xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView and xref:Microsoft.AspNetCore.Components.Authorization.CascadingAuthenticationState for the Blazor router:
<CascadingAuthenticationState>
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="@routeData"
DefaultLayout="@typeof(MainLayout)" />
...
</Found>
</Router>
</CascadingAuthenticationState>
Note
When you create a Blazor app from one of the Blazor project templates with authentication enabled, the app includes the xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView and xref:Microsoft.AspNetCore.Components.Authorization.CascadingAuthenticationState components shown in the preceding example. For more information, see xref:blazor/security/index#expose-the-authentication-state-as-a-cascading-parameter with additional information presented in the article's Customize unauthorized content with the Router component section.
An xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeView demonstrates the authenticated user's name in any component:
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
For guidance on the use of xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeView, see xref:blazor/security/index#authorizeview-component.
A custom AuthenticationStateProvider
can invoke xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider.NotifyAuthenticationStateChanged%2A on the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider base class to notify consumers of the authentication state change to rerender.
The following example is based on implementing a custom xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider by following the guidance in the Implement a custom AuthenticationStateProvider
section.
The following CustomAuthenticationStateProvider
implementation exposes a custom method, AuthenticateUser
, to sign in a user and notify consumers of the authentication state change.
CustomAuthenticationStateProvider.cs
:
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity();
var user = new ClaimsPrincipal(identity);
return Task.FromResult(new AuthenticationState(user));
}
public void AuthenticateUser(string userIdentifier)
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, userIdentifier),
}, "Custom Authentication");
var user = new ClaimsPrincipal(identity);
NotifyAuthenticationStateChanged(
Task.FromResult(new AuthenticationState(user)));
}
}
In a component:
- Inject xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider.
- Add a field to hold the user's identifier.
- Add a button and a method to cast the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider to
CustomAuthenticationStateProvider
and callAuthenticateUser
with the user's identifier.
:::moniker range=">= aspnetcore-8.0"
@rendermode InteractiveServer
@inject AuthenticationStateProvider AuthenticationStateProvider
<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
@code {
public string userIdentifier = string.Empty;
private void SignIn()
{
((CustomAuthenticationStateProvider)AuthenticationStateProvider)
.AuthenticateUser(userIdentifier);
}
}
:::moniker-end
:::moniker range="< aspnetcore-8.0"
@inject AuthenticationStateProvider AuthenticationStateProvider
<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
@code {
public string userIdentifier = string.Empty;
private void SignIn()
{
((CustomAuthenticationStateProvider)AuthenticationStateProvider)
.AuthenticateUser(userIdentifier);
}
}
:::moniker-end
The preceding approach can be enhanced to trigger notifications of authentication state changes via a custom service. The following AuthenticationService
maintains the current user's claims principal in a backing field (currentUser
) with an event (UserChanged
) that the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider can subscribe to, where the event invokes xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider.NotifyAuthenticationStateChanged%2A. With the additional configuration later in this section, the AuthenticationService
can be injected into a component with logic that sets the CurrentUser
to trigger the UserChanged
event.
using System.Security.Claims;
public class AuthenticationService
{
public event Action<ClaimsPrincipal>? UserChanged;
private ClaimsPrincipal? currentUser;
public ClaimsPrincipal CurrentUser
{
get { return currentUser ?? new(); }
set
{
currentUser = value;
if (UserChanged is not null)
{
UserChanged(currentUser);
}
}
}
}
:::moniker range=">= aspnetcore-6.0"
In the Program
file, register the AuthenticationService
in the dependency injection container:
builder.Services.AddScoped<AuthenticationService>();
:::moniker-end
:::moniker range="< aspnetcore-6.0"
In Startup.ConfigureServices
of Startup.cs
, register the AuthenticationService
in the dependency injection container:
services.AddScoped<AuthenticationService>();
:::moniker-end
The following CustomAuthenticationStateProvider
subscribes to the AuthenticationService.UserChanged
event. GetAuthenticationStateAsync
returns the user's authentication state. Initially, the authentication state is based on the value of the AuthenticationService.CurrentUser
. When there's a change in user, a new authentication state is created with the new user (new AuthenticationState(newUser)
) for calls to GetAuthenticationStateAsync
:
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private AuthenticationState authenticationState;
public CustomAuthenticationStateProvider(AuthenticationService service)
{
authenticationState = new AuthenticationState(service.CurrentUser);
service.UserChanged += (newUser) =>
{
authenticationState = new AuthenticationState(newUser);
NotifyAuthenticationStateChanged(
Task.FromResult(new AuthenticationState(newUser)));
};
}
public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
Task.FromResult(authenticationState);
}
The following component's SignIn
method creates a claims principal for the user's identifier to set on AuthenticationService.CurrentUser
:
:::moniker range=">= aspnetcore-8.0"
@rendermode InteractiveServer
@inject AuthenticationService AuthenticationService
<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
@code {
public string userIdentifier = string.Empty;
private void SignIn()
{
var currentUser = AuthenticationService.CurrentUser;
var identity = new ClaimsIdentity(
new[]
{
new Claim(ClaimTypes.Name, userIdentifier),
},
"Custom Authentication");
var newUser = new ClaimsPrincipal(identity);
AuthenticationService.CurrentUser = newUser;
}
}
:::moniker-end
:::moniker range="< aspnetcore-8.0"
@inject AuthenticationService AuthenticationService
<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
@code {
public string userIdentifier = string.Empty;
private void SignIn()
{
var currentUser = AuthenticationService.CurrentUser;
var identity = new ClaimsIdentity(
new[]
{
new Claim(ClaimTypes.Name, userIdentifier),
},
"Custom Authentication");
var newUser = new ClaimsPrincipal(identity);
AuthenticationService.CurrentUser = newUser;
}
}
:::moniker-end
Don't attempt to resolve xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider within a custom scope because it results in the creation of a new instance of the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider that isn't correctly initialized.
To access the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider within a service scoped to a component, inject the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider with the @inject
directive or the [Inject]
attribute and pass it to the service as a parameter. This approach ensures that the correct, initialized instance of the xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider is used for each user app instance.
ExampleService.cs
:
public class ExampleService
{
public async Task<string> ExampleMethod(AuthenticationStateProvider authStateProvider)
{
var authState = await authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
return $"{user.Identity.Name} is authenticated.";
}
else
{
return "The user is NOT authenticated.";
}
}
}
Register the service as scoped. In a server-side Blazor app, scoped services have a lifetime equal to the duration of the client connection circuit.
:::moniker range=">= aspnetcore-6.0"
In the Program
file:
builder.Services.AddScoped<ExampleService>();
:::moniker-end
:::moniker range="< aspnetcore-6.0"
In Startup.ConfigureServices
of Startup.cs
:
services.AddScoped<ExampleService>();
:::moniker-end
In the following InjectAuthStateProvider
component:
- The component inherits xref:Microsoft.AspNetCore.Components.OwningComponentBase.
- The xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider is injected and passed to
ExampleService.ExampleMethod
. ExampleService
is resolved with xref:Microsoft.AspNetCore.Components.OwningComponentBase.ScopedServices?displayProperty=nameWithType and xref:Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService%2A, which returns the correct, initialized instance ofExampleService
that exists for the lifetime of the user's circuit.
InjectAuthStateProvider.razor
:
:::moniker range=">= aspnetcore-8.0"
@page "/inject-auth-state-provider"
@rendermode InteractiveServer
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase
<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>
<p>@message</p>
@code {
private string? message;
private ExampleService? ExampleService { get; set; }
protected override async Task OnInitializedAsync()
{
ExampleService = ScopedServices.GetRequiredService<ExampleService>();
message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
}
}
:::moniker-end
:::moniker range="< aspnetcore-8.0"
@page "/inject-auth-state-provider"
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase
<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>
<p>@message</p>
@code {
private string? message;
private ExampleService? ExampleService { get; set; }
protected override async Task OnInitializedAsync()
{
ExampleService = ScopedServices.GetRequiredService<ExampleService>();
message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
}
}
:::moniker-end
For more information, see the guidance on xref:Microsoft.AspNetCore.Components.OwningComponentBase in xref:blazor/fundamentals/dependency-injection#owningcomponentbase.
To avoid showing unauthorized content while prerendering with a custom AuthenticationStateProvider
, adopt one of the following approaches:
-
Implement xref:Microsoft.AspNetCore.Components.Authorization.IHostEnvironmentAuthenticationStateProvider for the custom xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider to support prerendering: For an example implementation of xref:Microsoft.AspNetCore.Components.Authorization.IHostEnvironmentAuthenticationStateProvider, see the Blazor framework's xref:Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider implementation in
ServerAuthenticationStateProvider.cs
(reference source).
:::moniker range=">= aspnetcore-8.0"
-
Disable prerendering: Indicate the render mode with the
prerender
parameter set tofalse
at the highest-level component in the app's component hierarchy that isn't a root component.[!NOTE] Making a root component interactive, such as the
App
component, isn't supported because the Blazor script may be evaluated multiple times. Therefore, prerendering can't be disabled directly by theApp
component.For apps based on the Blazor Web App project template, prerendering is typically disabled where the
Routes
component is used in theApp
component (Components/App.razor
) :<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Also, disable prerendering for the
HeadOutlet
component:<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
:::moniker-end
:::moniker range="< aspnetcore-8.0"
-
Disable prerendering: Open the
_Host.cshtml
file and change therender-mode
attribute of the Component Tag Helper to xref:Microsoft.AspNetCore.Mvc.Rendering.RenderMode.Server:<component type="typeof(App)" render-mode="Server" />
:::moniker-end
- Authenticate the user on the server before the app starts: To adopt this approach, the app must respond to a user's initial request with the Identity-based sign-in page or view and prevent any requests to Blazor endpoints until they're authenticated. For more information, see xref:security/authorization/secure-data#require-authenticated-users. After authentication, unauthorized content in prerendered Razor components is only shown when the user is truly unauthorized to view the content.
In spite of the word "state" in the name, xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider isn't for storing general user state. xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider only indicates the user's authentication state to the app, whether they are signed into the app and who they are signed in as.
Authentication uses the same ASP.NET Core Identity authentication as Razor Pages and MVC apps. The user state stored for ASP.NET Core Identity flows to Blazor without adding additional code to the app. Follow the guidance in the ASP.NET Core Identity articles and tutorials for the Identity features to take effect in the Blazor parts of the app.
For guidance on general state management outside of ASP.NET Core Identity, see xref:blazor/state-management?pivots=server.
Two additional abstractions participate in managing authentication state:
-
xref:Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider (reference source): An xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider used by the Blazor framework to obtain authentication state from the server.
-
xref:Microsoft.AspNetCore.Components.Server.RevalidatingServerAuthenticationStateProvider (reference source): A base class for xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider services used by the Blazor framework to receive an authentication state from the host environment and revalidate it at regular intervals.
The default 30 minute revalidation interval can be adjusted in
RevalidatingIdentityAuthenticationStateProvider
(Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs
). The following example shortens the interval to 20 minutes:protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(20);
:::moniker range=">= aspnetcore-8.0"
This section applies to Blazor Web Apps.
Use the TemporaryRedirectionUrlValidityDuration
option to get or set the lifetime of data protection validity for temporary redirection URLs emitted by Blazor server-side rendering. These are only used transiently, so the lifetime only needs to be long enough for a client to receive the URL and begin navigation to it. However, it should also be long enough to allow for clock skew across servers. The default value is five minutes.
In the following example the value is extended to seven minutes:
builder.Services.AddRazorComponents(options =>
options.TemporaryRedirectionUrlValidityDuration =
TimeSpan.FromMinutes(7));
:::moniker-end
- Quickstart: Add sign-in with Microsoft to an ASP.NET Core web app
- Quickstart: Protect an ASP.NET Core web API with Microsoft identity platform
- xref:host-and-deploy/proxy-load-balancer: Includes guidance on:
- Using Forwarded Headers Middleware to preserve HTTPS scheme information across proxy servers and internal networks.
- Additional scenarios and use cases, including manual scheme configuration, request path changes for correct request routing, and forwarding the request scheme for Linux and non-IIS reverse proxies.