Forum Discussion
AllowAnonymous attribute not working
Hi,
I have a .NET Core 10 MVC web app and I want to create views that can be viewed without requiring login. I have tried adding [AllowAnonymous] both to my controller and to individual views, but the user always gets redirected to the login screen. I am thinking that it must be due to the setup in my Program.cs.
Here is my Program.cs :
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(
options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection"),
x => x.MigrationsAssembly("PBP")));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
//require this for editing syncfusion datagrid
builder.Services.AddMvc().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
builder.Services.AddTransient<SessionHelper>();
builder.Services.AddApplicationInsightsTelemetry(new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions
{
ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]
});
//session
//https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-7.0
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(1200);
options.Cookie.Name = ".PBP.Session";
options.Cookie.IsEssential = true;
});
builder.Services.ConfigureApplicationCookie(options =>
{
//options.ExpireTimeSpan = TimeSpan.FromSeconds(1800); //default is 14 days
options.LoginPath = "/Identity/Account/Login";
options.SlidingExpiration = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/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.MapStaticAssets();
app.UseRouting();
app.UseAuthorization();
app.UseSession();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto
});
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}").WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Can anybody advise me on if this is the issue and if so what changes I need to make so that I can successfully use AllowAnonymous?
Many thanks,
Mike
3 Replies
- M-SalisouCopper Contributor
Hi,
There are two distinct issues at play here: one structural flaw in your middleware pipeline configuration, and a conceptual misunderstanding regarding how ASP.NET Core attributes operate.
1. Missing app.UseAuthentication() Middleware (Primary Issue)
In your Program.cs, you have registered app.UseAuthorization(), but omitted app.UseAuthentication().
Authorization depends strictly on Authentication running earlier in the pipeline to construct the ClaimsPrincipal context. Without UseAuthentication(), the pipeline cannot correctly process identity schemes, leading to unexpected fallback redirects to the Login route.
Modify your request pipeline order in Program.cs as follows:
app.UseRouting();
// MUST be called after UseRouting() and BEFORE UseAuthorization()
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
2. Attribute Application Scope
You mentioned attempting to apply [AllowAnonymous] to individual views. In ASP.NET Core MVC:
Attributes like [AllowAnonymous] or [Authorize] are evaluated by the endpoint routing and action invocation infrastructure.
They can only be placed on Controller classes or Action methods (.cshtml.cs PageModels in Razor Pages), not directly inside Razor View (.cshtml) files.
Ensure your controller action is decorated like this:
[AllowAnonymous]
public IActionResult PublicView()
{
return View();
}
Once app.UseAuthentication() is placed before app.UseAuthorization(), your [AllowAnonymous] attribute on controller actions will be evaluated correctly by the framework.
Hope this helps!😉
- Ghaith-ShammoutCopper Contributor
Hi MikeMP,
I just saw your post and I think I can help.
First thing I would do is to apply authentication to your program by adding
app.UseAuthentication()right before authorization so it becomes
app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseSession();Without UseAuthentication(), Identity cannot establish the user principal correctly.
However, that alone may not be the root cause, [AllowAnonymous] should override authorization requirements. If requests are still being redirected to login, I guess there is a global authorization policy somewhere in your code.
If you have a fallback policy, then [AllowAnonymous] should still work. If it doesn't, there may be another filter or middleware forcing authentication.
One thing you can try, create a completely anonymous controller, like:
[AllowAnonymous] public class TestController : Controller { public IActionResult Public() { return Content("Public page"); } }Then browse to:
/Test/PublicIf that still redirects to:
/Identity/Account/Loginthen the problem is almost certainly a global authorization policy, custom middleware, or a base controller containing [Authorize].
Hope this helps,
Kindly reply if it did or did not help, and how you have solved the problem if you already did.
AllowAnonymous is appropriate on an MVC controller or action, but it has no effect when placed on a Razor view. Your pipeline is also missing authentication middleware. Add app.UseAuthentication() after app.UseRouting() and immediately before app.UseAuthorization(); keep session after authorization and before the mapped endpoints. The relevant section should be: app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseSession();. Then place [AllowAnonymous] on the controller class or the specific public action and browse directly to that action’s route. AllowAnonymous bypasses authorization requirements for that endpoint, although authentication may still identify a signed-in user. If it still redirects, inspect the selected endpoint’s metadata and any custom middleware, global MVC filter, base controller, or rewrite rule that sends anonymous users to /Identity/Account/Login. Also move UseForwardedHeaders near the start of the pipeline, before HTTPS redirection, when running behind a trusted proxy. That ordering is separate from AllowAnonymous but prevents incorrect scheme or client information from influencing redirects.