Describe the bug
When using cookie authentication, the AccessDeniedPath config parameter seems to be ignored. This has worked previously (though I haven't done the testing to determine if the behavior changed in 2.0 or 2.0.x). It's always possible that I'm not doing it right, and I welcome correction if that's the case.
Bug Details
Here's the startup configuration in a trivial test app:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(coptions => new CookieAuthenticationOptions()
{
LoginPath = new PathString("/account/login"),
AccessDeniedPath = new PathString("/account/forbidden"),
ExpireTimeSpan = TimeSpan.FromMinutes(5),
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context => { await ValidatePrincipal(context); }
}
});
}
Expected Behavior
After logging in and when requesting a protected resource without the required role (i.e. action decorated with [Authorize(Role = "NotMyRole")]), should be redirected to configured AccessDeniedPath (i.e. "/account/forbidden").
Actual Behavior
After logging in and requesting a protected resource without the required role, application redirects to a constant value of "/Account/AccessDenied" resulting in a 404 if that route/action does not exist.
Workaround
Simply handle "/account/accessdenied" by route or coded action.
Additional context
I've noticed that the current cookie sample project exhibits this same problem (configured "/account/denied", but the action in AccountController is AccessDenied).
https://github.com/aspnet/AspNetCore/tree/master/src/AuthSamples/samples/Cookies
Repro sample project
TrivialWebAppAccessPathDeniedIssue.zip
To use the attached sample, run it and then attempt to go to the About page. The resulting 404 error demonstrates the problem. See Startup.cs and AccountController.cs for the interesting bits.
Answer:
It's using the wrong options object.
Fixed:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(coptions =>
{
coptions.LoginPath = new PathString("/account/login");
coptions.AccessDeniedPath = new PathString("/account/forbidden");
coptions.ExpireTimeSpan = TimeSpan.FromMinutes(5);
coptions.Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context => { await ValidatePrincipal(context); }
};
});
No comments:
Post a Comment