Tuesday 20 December 2022

AccessDeniedPath ignored in CookieAuthenticationOptions in Dot Net Core

 

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