I have a Blazor Wasm application with custom authentication in .net 8.
The authentication works fine when I follow a navlink but if I enter the url of the page directly then it throws a 401 error. It never even enters the code on the page. It is like the internal routing is doing something. For instance if I am not logged in and I go to the page then I am redirected to the login page. However if I go directly to the page url it just shows a browser 401 page so it has not routed me to login (Not that it should as I am already logged in). If I go back to the home page and click the link to the page then it works fine.
here is my Routes.razor
<Router AppAssembly="typeof(Program).Assembly"><Found Context="routeData"><AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)"><NotAuthorized> @{ var returnUrl = navManager.ToBaseRelativePath(navManager.Uri);<RedirectToLogin ReturnUrl="@returnUrl" /> }</NotAuthorized></AuthorizeRouteView><FocusOnNavigate RouteData="routeData" Selector="h1" /></Found></Router>Here is my razor page
@page "/masterstock"@using Microsoft.AspNetCore.Authorization@using Microsoft.AspNetCore.Components.Authorization@inject HttpClient Http@attribute [Authorize]<h3>MyPage</h3>@code { [CascadingParameter] public Task<AuthenticationState> AuthState { get; set; } protected override async Task OnInitializedAsync() { var authState = await AuthState; if (authState.User.Identity.IsAuthenticated) { string asdasas = string.Empty; } else { string asasasaaa = string.Empty; } }}Here is the server project Program.cs
var builder = WebApplication.CreateBuilder(args);var config = builder.Configuration;builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);//builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true);//builder.Configuration.AddJsonFile($"appsettings.local.json", optional: true);// Add services to the container.builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents();builder.Services.AddControllers(); // Add this linebuilder.Services.AddRazorPages();builder.Services.AddAuthenticationCore();builder.Services.AddAuthorizationCore();builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{ var jwtSettings = config.GetSection("JWTSettings"); options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSettings["validIssuer"], ValidAudience = jwtSettings["validAudience"], ClockSkew = new TimeSpan(0, 1, 0), IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["securityKey"])) };});var app = builder.Build();// Configure the HTTP request pipeline.if (app.Environment.IsDevelopment()){ app.UseWebAssemblyDebugging();}else{ app.UseExceptionHandler("/Error", createScopeForErrors: true); // 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.UseAuthentication();app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting(); // Add this lineapp.UseAntiforgery();app.UseAuthorization(); // Add this lineapp.MapControllers();app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(MyWeb.Client._Imports).Assembly);app.Run();And the Program.cs for the Client App
var builder = WebAssemblyHostBuilder.CreateDefault(args);builder.Services.AddAuthorizationCore();builder.Services.AddCascadingAuthenticationState();builder.Services.AddHttpClient("MyWeb.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });builder.Services.AddBlazoredLocalStorage();builder.Services.AddSingleton<AuthenticationStateProvider, CustomAuthStateProvider>();builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();await builder.Build().RunAsync();Note that I have discovered that it is not hitting the CustomAuthStateProvider if I refresh the page... Is this part of the issue?