Goal
I want to route to my login page when I am not authorized.
I use AspNet with Entity Framework in a MudBlazor WebApp
Problem
The problem is that my browser keeps saying
The page isn’t redirecting properlyWhen I put a breakpoint in my OnInitializedAsync in RedirectToLogin.razor i recognize an infinite loop.
What I tried
- using
LoginPagedirectly
<NotAuthorized><LoginPage/></NotAuthorized>But then there is no navigation URI in the browsers searchbar
- wrapping the LoginPage in LoginLayout results in infinite loop also
<NotAuthorized><LayoutView Layout="typeof(LoginLayout)"><RedirectToLogin/></LayoutView></NotAuthorized>- using
@attribute [Authorize]redirects always toAccount/Login?ReturnUrl=%2F - using
@attribute [Authorize]and changing LoginPage to@page "/Account/Login"and using this code
<AuthorizeView><Authorized><RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/></Authorized><NotAuthorized><RouteView RouteData="@routeData" DefaultLayout="@typeof(LoginLayout)" /></NotAuthorized></AuthorizeView>seems to work but I cant use a custom route except Account/Login
Code
Routes.razor
<CascadingAuthenticationState><Router AppAssembly="@typeof(Program).Assembly"><Found Context="routeData"><AuthorizeView><Authorized><RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/></Authorized><NotAuthorized><RedirectToLogin/></NotAuthorized></AuthorizeView></Found><NotFound><LayoutView Layout="@typeof(MainLayout)"><p>Sorry, there's nothing at this address.</p></LayoutView></NotFound></Router></CascadingAuthenticationState>MainLayout.razor
@inherits LayoutComponentBase<MudLayout><MudAppBar Elevation="1"><MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@(e => DrawerToggle())" /><MudSpacer /><MudIconButton Icon="@Icons.Material.Filled.MoreVert" Color="Color.Inherit" Edge="Edge.End" /></MudAppBar><MudDrawer @bind-Open="_drawerOpen" Elevation="2"><MudDrawerHeader><MudText Typo="Typo.h5" Class="mt-1">MyApp</MudText></MudDrawerHeader><NavMenu/></MudDrawer><MudMainContent> @Body</MudMainContent></MudLayout>@code { bool _drawerOpen = true; void DrawerToggle() { _drawerOpen = !_drawerOpen; }}RedirectToLogin.razor
@inject NavigationManager NavigationManager@code { protected override async Task OnInitializedAsync() { NavigationManager.NavigateTo("Login", forceLoad: true); }}LoginLayout.razor
<MudLayout><p>LoginLayout</p><MudMainContent> @Body</MudMainContent></MudLayout>@code {}LoginPage.razor
@page "/Login"<h3>LoginPage</h3>@code {}And App.razor and Program.cs maybe it helps...
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 rel="stylesheet" href="CompanyKnowledgeAIClient.styles.css" /><link rel="icon" type="image/png" href="favicon.ico" /> @* Mudblazor - Add font and style references *@<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" /><HeadOutlet /></head><body><Routes /> @* Mudblazor - Add script reference *@<script src="_framework/blazor.web.js"></script><script src="_content/MudBlazor/MudBlazor.min.js"></script></body></html>Program.cs
var builder = WebApplication.CreateBuilder(args);// Add DbContextsbuilder.Services.AddDbContext<PostgresDbContext>();builder.Services.AddDbContext<MySqlDbContext>();// Add services to the container.builder.Services.AddRazorComponents() .AddInteractiveServerComponents();// MudBlazor Servicesbuilder.Services.AddMudServices();builder.Services.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>();// Detailed error output on circuitbuilder.Services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; });// Authenticationbuilder.Services.AddAuthentication(options => { options.DefaultScheme = IdentityConstants.ApplicationScheme; options.DefaultSignInScheme = IdentityConstants.ExternalScheme; }) .AddIdentityCookies();// Identitybuilder.Services.AddIdentityCore<IdentityUser>() .AddEntityFrameworkStores<MySqlDbContext>() .AddSignInManager() .AddDefaultTokenProviders();var app = builder.Build();// Configure the HTTP request pipeline.if (!app.Environment.IsDevelopment()){ app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseAntiforgery();app.MapRazorComponents<App>() .AddInteractiveServerRenderMode();app.Run();