I have a Blazor web app with .NET 8. I am trying to configure the app so that certain pages route users to the login page.
I have it working, except that the redirect only happens when I reload the page. I can view the full page when I navigate to it via the nav menu. Once I hit reload I am redirected to login and can verify that I am logged in.
I intended it to have a user redirected to the login page after I click the page that needs authenticating.
Below is my code. I am aware of <Authorized> and <NotAuthorized> and that I can easily throw in a <NotAuthorized> with a child component on my App.razor to manually do the redirect. However, I see no reason why what I have below does not work, and I hope to understand more.
Program.cs
using Microsoft.AspNetCore.Authentication.OpenIdConnect;using MudBlazor.Services;using Microsoft.Identity.Web;using Microsoft.Identity.Web.UI;using WebApp.Components;var builder = WebApplication.CreateBuilder(args);var initialScopes = builder.Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split('');// Add Authenticationbuilder.Services .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));builder.Services .AddControllersWithViews() .AddMicrosoftIdentityUI();builder.Services.AddAuthorizationCore();// Add services to the container.builder.Services .AddRazorComponents() .AddInteractiveServerComponents();// Add MudBlazor servicesbuilder.Services.AddMudServices();var app = builder.Build();// Configure the HTTP request pipeline.if (!app.Environment.IsDevelopment()){ app.UseExceptionHandler("/Error", createScopeForErrors: true); app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseAuthentication(); // Enable authenticationapp.UseAuthorization();app.UseAntiforgery();app.MapRazorComponents<App>() .AddInteractiveServerRenderMode();app.Run();Routes.razor
<Router AppAssembly="typeof(Program).Assembly"><Found Context="routeData"><AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" /><FocusOnNavigate RouteData="routeData" Selector="h1" /></Found></Router>App.razor
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><base href="/" /> <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" /><link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" /> <link rel="icon" type="image/ico" href="favicon.ico" /><HeadOutlet @rendermode="InteractiveServer" /></head><body><Routes @rendermode="InteractiveServer" /><script src="_framework/blazor.web.js"></script><script src="_content/MudBlazor/MudBlazor.min.js"></script></body></html>Weather.razor
@page "/weather"@attribute [Authorize]<PageTitle>Weather</PageTitle><MudText Typo="Typo.h3" GutterBottom="true">Weather forecast</MudText><MudText Typo="Typo.body1" Class="mb-8">This component demonstrates fetching data from the server.</MudText>@if (forecasts == null){<MudProgressCircular Color="Color.Default" Indeterminate="true" />}else{<MudTable Items="forecasts" Hover="true" SortLabel="Sort By" Elevation="0" AllowUnsorted="false"><HeaderContent><MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<WeatherForecast, object>(x=>x.Date)">Date</MudTableSortLabel></MudTh><MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureC)">Temp. (C)</MudTableSortLabel></MudTh><MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureF)">Temp. (F)</MudTableSortLabel></MudTh><MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.Summary!)">Summary</MudTableSortLabel></MudTh></HeaderContent><RowTemplate><MudTd DataLabel="Date">@context.Date</MudTd><MudTd DataLabel="Temp. (C)">@context.TemperatureC</MudTd><MudTd DataLabel="Temp. (F)">@context.TemperatureF</MudTd><MudTd DataLabel="Summary">@context.Summary</MudTd></RowTemplate><PagerContent><MudTablePager PageSizeOptions="new int[]{50, 100}" /></PagerContent></MudTable>}@code { private WeatherForecast[]? forecasts; protected override async Task OnInitializedAsync() { // Simulate asynchronous loading to demonstrate a loading indicator await Task.Delay(500); var startDate = DateOnly.FromDateTime(DateTime.Now); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = startDate.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = summaries[Random.Shared.Next(summaries.Length)] }).ToArray(); } private class WeatherForecast { public DateOnly Date { get; set; } public int TemperatureC { get; set; } public string? Summary { get; set; } public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); }}Thank you in advance!