I have a Blazor web app (.NET 8) with interactive render mode WebAssembly, and I use https://github.com/IUCrimson/AspNet.Security.CAS for authentication. It's mostly working great, and I can see my claims on the client and server. However, authorization only works for Razor pages. The authorize attribute on my controller is ignored. Is there some step I am missing in my setup?
Program.cs
using AspNetCore.Security.CAS;using Microsoft.AspNetCore.Authentication.Cookies;using Microsoft.AspNetCore.Authorization.Policy;using Microsoft.AspNetCore.Components.Authorization;using Microsoft.Extensions.DependencyInjection.Extensions;using Microsoft.FluentUI.AspNetCore.Components;using System.Security.Claims;var builder = WebApplication.CreateBuilder(args);ConfigurationManager configuration = builder.Configuration;IWebHostEnvironment environment = builder.Environment;builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents();builder.Services.AddScoped<AuthenticationStateProvider, PersistingServerAuthenticationStateProvider>();builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.AccessDeniedPath = "/AccessDenied"; options.Cookie.SameSite = SameSiteMode.Strict; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.ExpireTimeSpan = TimeSpan.FromHours(1); // set to match CAS timeout options.LoginPath = new PathString("/api/login"); options.SlidingExpiration = false; options.Events = new CookieAuthenticationEvents { OnSigningIn = context => { var _dal = new DatabaseService(configuration); var principal = context.Principal; ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity; var claims = new List<Claim> { new(ClaimTypes.Role, "ADMIN") }; identity.AddClaims(claims); return Task.FromResult(0); } }; }) .AddCAS(options => { options.CasServerUrlBase = "myCasServer"; options.ServiceForceHTTPS = true; options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; });builder.Services.AddHttpClient();builder.Services.AddSingleton<DatabaseService, DatabaseService>();builder.Services.AddControllers();builder.Services.AddFluentUIComponents();var app = builder.Build();if (app.Environment.IsDevelopment()) { app.UseWebAssemblyDebugging();} else { app.UseExceptionHandler("/Error", createScopeForErrors: true); app.UseHsts();}app.UseHttpsRedirection();app.UseAuthentication();app.UseAuthorization();app.UseStaticFiles();app.UseAntiforgery();app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(OnlinePab.Client._Imports).Assembly);app.MapControllers();app.Run();Controller
using Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;namespace Boo.Controllers { [Authorize(Roles = "NOBODY")] [Route("api")] [ApiController] public class MyController() : ControllerBase { [AllowAnonymous] [Route("login")] public async Task Login(string returnUrl) { var props = new AuthenticationProperties { RedirectUri = returnUrl }; await HttpContext.ChallengeAsync("CAS", props); } [Route("boo")] public ContentResult NotAllowed() { return base.Content("<div>Boo!</div>", "text/html"); } }}