Search code examples
asp.net-corecookiesmodel-view-controllerauthorization

asp.net core mvc .net8 return custom view on 403


How I can show custom forbidden view?

My asp.net core mvc project have cookie based authorization

      services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.LoginPath = "/Authorization/Login";
                options.AccessDeniedPath = "/Account/AccessDenied";
            });

There are my policies


        services.AddAuthorizationBuilder()
            .SetDefaultPolicy(new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme)
                .RequireAuthenticatedUser()
                .Build())
            .AddPolicy(ApplicationPolicies.SuperAdministrator, op => op
                .RequireRole(ApplicationClaimValues.SuperAdministrator))
            .AddPolicy(ApplicationPolicies.Administrator, op => op
                .RequireRole(ApplicationClaimValues.SuperAdministrator, ApplicationClaimValues.Administrator))
            .AddPolicy(ApplicationPolicies.Reviewer, op => op
                .RequireRole(ApplicationClaimValues.Reviewer, ApplicationClaimValues.Administrator,
                    ApplicationClaimValues.SuperAdministrator));

How can I show view on Shared/ExtraPages/Forbidden.cshtml when AuthorizeAttribute on my action:

    [HttpPost]
    public async Task<IActionResult> Create(CreateContentCommand command)
    {
        await mediator.Send(command);
        return Redirect($"{Url.Action("Index")}?pageName={command.PageName}");
    }

gives 403 status code?

Now I'm getting an empty response from the server with a 403 status.


Solution

  • According to your codes, your AccessDeniedPath is /Account/AccessDenied. So if you want to return the custom 403 fordden page, you should write the Account controller and the AccessDenied view.

    Then inside this AccessDenied view, you could set content according to your requirement.

    More details, you could refer to below example:

    [AllowAnonymous]
    public class AccountController : Controller
    {
    
        public IActionResult AccessDenied()
        {
            return View();
        }
    }
    

    View:

    @{
        ViewData["Title"] = "AccessDenied";
    }
    
    <h1>AccessDenied</h1>
    
    AccessDenied
    

    My Authorize attribute:

    [Authorize(Policy = "test")]
    public IActionResult Privacy()
    {
        return View();
    }
    

    My program.cs:

    builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
          .AddCookie(options =>
          {
              options.LoginPath = "/Authorization/Login";
              options.AccessDeniedPath = "/Account/AccessDenied";
          });
    
    
    builder.Services.AddAuthorizationBuilder()
        .SetDefaultPolicy(new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser()
            .Build())
        .AddPolicy("test", op => op
            .RequireRole("admin"));
    

    Result:

    enter image description here