Search code examples
asp.net-mvcasp.net-core.net-7.0

How to know if the controller or action has Authorize attribute using HttpContext.Features.Get<IExceptionHandlerPathFeature>()?


I have a common ErrorController to handle the errors in the ASP.NET Core MVC application which has an Error view in the Shared folder. I have two Layouts one for Authenticated users (_layoutAuth) and one for anonymous users (_layoutAnony). I want to set the Layout of the Error view depending on whether the error comes from the Controller or Action having Authorize attribute. For example, in the below code, if the error comes from SalesController, the Layout of the Error view should be _layoutAuth and if the error comes from HomeController, the Layout of the Error view should be _layoutAnony. I've tried on the Error action in the ErrorController to know if the controller or action has an Authorize attribute or not show that I could determine which layout to choose but was unable to get the right value. Could anyone help me achieve it?

ErrorController.cs

public class ErrorController : Controller
{       
    [Route("Error")]
    [AllowAnonymous]
    public IActionResult Error()
    {
        var exceptionDetails = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
       // I want to check here if the controller has Authorize attribute with Controller 
       //level or action level

        ViewBag.Layout = ???;
        ViewBag.ErrorMessage = exceptionDetails?.Error.Message;

        return View("Error");
    }
}

SalesController.cs

public class SalesController : Controller
{
    
        [Authorize]
        public ActionResult Index()
        {
           throw new Exception("Exception from SalesController.");
           return View();
      }
}

HomeController.cs

public class HomeController : Controller
{   
          
        public ActionResult Index()
        {
           throw new Exception("Exception from HomeController.");
           return View();
      }
}

Solution

  • Using asp.net core Identity user claim we can check if the user is authenticated. On the other hand using request header we can also check if that containing autthorization value.

    I have tested the scenario as following:

    Controller:

    public class ErrorController : Controller
        {
            public IActionResult Error()
            {
                string authHeader = HttpContext.Request.Headers["Authorization"];
                if (authHeader == null)
                {
                    ViewData["page"] = "_ErrorLayout";
                }
                return View();
            }
        }
    

    _ViewStart.cshtml:

    @{
         switch (ViewData["page"])
            {
                case "_ErrorLayout":
                    Layout = "_ErrorLayout";
                    break;
                case "Users":
                    Layout = "_UserLayout";
                    break;
                default:
                    Layout = "_Layout";
                    break;
            }
           
        }
    

    enter image description here

    _ErrorLayout:

    <h1>This is error layout</h1>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>
    

    Output:

    enter image description here