A website is per default anonymous access only.
The admin has a button to switch the site into maintenance mode, which should enable authorization using the built-in CookieAuthentication (flip a bit in a database, not relevant for this post).
In order to make that work, I first configured cookie authentication (in startup.cs):
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.LoginPath = new PathString("/auth/login");
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
}
Then on relevant controllers, I put an [Authorize] attribute.
[Authorize]
public class HomeController : Controller
{
//removed
}
This works perfectly - cookie auth kicks in when authorize-attribute is present. So far so good.
Now I want to disable authorization at runtime when maintenance mode is off.
Attempted Solution
This is what I ended up with after a lot of trial and error and research.
public void OnAuthorization(AuthorizationFilterContext context)
{
IMaintenanceModeDataService ds = context.HttpContext.RequestServices.GetService<IMaintenanceModeDataService>();
if (!ds.IsMaintenanceModeEnabled)
{
//Maintenance mode is off, no need for authorization
return;
}
else
{
ClaimsPrincipal user = context.HttpContext.User;
if (user.Identity.IsAuthenticated)
{
//when the user is authenticated, we don't need to do anything else.
return;
}
else
{
//we're in maintenance mode AND the user is not
//It is outside the scope of this to redirect to a login
//We just want to display maintenancemode.html
context.Result = new RedirectResult("/maintenancemode.html");
return;
}
}
}
[MaintenanceModeAwareAuthorize]
public class HomeController : Controller
{
//removed
}
This works great when the site is in maintenance mode.
When the site is NOT in maintenance mode, the cookie authentication still kicks in and requires auth. I could remove that and try to implement my own auth, but that would be stupid, when we already have perfectly well-crafted solutions built-in.
How do I disable authorization when the site is NOT in maintenance mode (at runtime)?
Notes:
Q: Why not handle this by doing x (which requires serverside access to config, environment vars, server or similar)?
A: Because this needs to be immediately accessible to non-technical admin-users by clicking a button in the backend.