I have a Blazor NET 8 Web Application. Currently working towards using Cookies as authentication. The login is being handled by a middleware class which does send the unauthorized user to /Login, but the blazor.web.js is not loading with an error of :
Uncaught SyntaxError: Unexpected token '<'
On a Status Code 302 Redirect
I have been looking all over for answers on how to resolve this.
Service Injection:
// Collection of Services to Inject into the Applicationpublic static IServiceCollection AddServerUI(this IServiceCollection services, IConfiguration config){ // Add LdapAuthenticationService services.AddHttpContextAccessor(); services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>(); services.AddScoped<LdapAuthenticationService>(); // Bind LdapRoleMappings from configuration and add LdapRoleMappingConfig var ldapRoleMappingConfig = new LdapRoleMappingConfig(); config.Bind("LdapRoleMappings", ldapRoleMappingConfig); services.AddSingleton(ldapRoleMappingConfig); var ldapServerList = new LdapServerList(config); services.AddSingleton(ldapServerList); // Adds Blazor Server render mode and components services.AddRazorComponents() .AddInteractiveServerComponents(); // Configure authentication services.AddCascadingAuthenticationState(); services.AddScoped<CookieEvents>(); services.AddAuthentication("Cookies") .AddCookie(options => { options.LogoutPath = "/Logout"; options.AccessDeniedPath = "/AccessDenied"; options.ExpireTimeSpan = TimeSpan.FromMinutes(60); // Set the cookie expiration time options.SlidingExpiration = true; // Enable sliding expiration options.EventsType = typeof(CookieEvents); }); // Configure authorization policies services.AddAuthorization(options => { options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin")); options.AddPolicy("RequireUserRole", policy => policy.RequireRole("User")); options.AddPolicy("RequireManagerRole", policy => policy.RequireRole("Manager")); options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); }); //services.AddSingleton<IAuthorizationMiddlewareResultHandler, AuthorizationMiddlewareResultHandler>(); // Mud Blazor UI Library Add In services.AddMudServices(); services.AddMudBlazorSnackbar(); services.AddMudServicesWithExtensions(); // Add ThemeService services.AddScoped<ThemeService>(); // Load Controllers from /Controllers Folder services.AddControllers(); // IAppConfiguration holds Object with appsettings.JSON Loaded services.AddSingleton<IAppConfiguration>(new ServerAppConfiguration(config)); // Http Client services.AddHttpClient(); // Service to have run only in DEV mode. #if DEV #endif return services;}// Build Configuration Injection for Applicationpublic static WebApplication ConfigureServer(this WebApplication app, IConfiguration config){ // Resolve IAppConfiguration from the services var appConfiguration = app.Services.GetRequiredService<IAppConfiguration>(); // Middleware to set Path Base off BaseUrl in AppSettings.json Configuration var baseUrl = appConfiguration.BaseUrl; app.UsePathBase(baseUrl); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error", createScopeForErrors: true); } // Allow Loading of Static files from wwwroot folder app.UseStaticFiles(); // Route Tables app.UseRouting(); // Authentication and Authorization Configuration app.UseAuthentication(); app.UseAuthorization(); app.UseAntiforgery(); app.UseHttpsRedirection(); /// Configuration loading for Controllers app.MapControllers(); // Maps Components to the Application in Server Render Mode app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); return app;}CustomAuthenticationStateProvider:
private ClaimsPrincipal _currentUser = new ClaimsPrincipal(new ClaimsIdentity()); public override Task<AuthenticationState> GetAuthenticationStateAsync() { return Task.FromResult(new AuthenticationState(_currentUser)); } public void NotifyAuthenticationStateChanged(ClaimsPrincipal user) { _currentUser = user; NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser))); }CookieEvents.cs:
public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> context) { context.RedirectUri = "/Login"; return base.RedirectToLogin(context); }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="/" /><!-- CSS Library Imports --><link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" /><link href="_content/MudBlazor.Extensions/mudBlazorExtensions.min.css" rel="stylesheet" id="mudex-styles"><HeadOutlet @rendermode="InteractiveServer" /></head><body><Routes @rendermode="InteractiveServer" /><div id="blazor-error-ui"> An unhandled error has occurred.<a href="" class="reload">Reload</a><a class="dismiss">🗙</a></div><!-- JS Library Imports --><script src="_framework/blazor.web.js"></script><script src="_content/MudBlazor/MudBlazor.min.js"></script></script></body></html>Routes.RazorSets Public Layout to use with /Login
<Router AppAssembly="typeof(Program).Assembly"><Found Context="routeData"><AuthorizeView><Authorized><RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" /></Authorized><NotAuthorized><RouteView RouteData="routeData" DefaultLayout="typeof(PublicLayout)" /></NotAuthorized></AuthorizeView><FocusOnNavigate RouteData="routeData" Selector="h1" /></Found></Router>Login.Razor
@page "/Login"@attribute [AllowAnonymous]I have tried using this approach:
public class AuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler { public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { return next(context); } }But this doesn't enforce rerouting to /Login
Looking for some advice, I have seen various suggestions around this problem but nothing is really fixing the issue here:
Rerouting to /Login, but having blazor.web.js load in correctly after rerouting.
I have not found a specific solution that matches this problem, apologize if I missed something.