ASP.NET MVC user friendly 401 error

后端 未结 4 1713
太阳男子
太阳男子 2020-12-05 07:56

I have implemented errors handling in ASP.NET MVC site in a way like suggests this post.

With 404 errors all works fine. But how correctly show user friendly screen

相关标签:
4条回答
  • 2020-12-05 08:21

    Look at the HandleErrorAttribute. Subclass from it or add your own implementation which will handle all the status codes you're interested in. You can make it to return a separate error view for each error type.

    Here is an idea of how to create your handle error exception filter. I've thrown out most of the stuff to only focus on our essentials. Absolutely have a look at the original implementation to add arguments checks and other important things.

    public class HandleManyErrorsAttribute : FilterAttribute, IExceptionFilter
    {
        public virtual void OnException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
                return;
    
            Exception exception = filterContext.Exception;
    
            string viewName = string.Empty;
            object viewModel = null;
            int httpCode = new HttpException(null, exception).GetHttpCode();
            if (httpCode == 500)
            {
                viewName = "Error500View";
                viewModel = new Error500Model();
            }
            else if (httpCode == 404)
            {
                viewName = "Error404View";
                viewModel = new Error404Model();
            }
            else if (httpCode == 401)
            {
                viewName = "Error401View";
                viewModel = new Error401Model();
            }
    
            string controllerName = (string)filterContext.RouteData.Values["controller"];
            string actionName = (string)filterContext.RouteData.Values["action"];
            filterContext.Result = new ViewResult
            {
                ViewName = viewName,
                MasterName = Master,
                ViewData = viewModel,
                TempData = filterContext.Controller.TempData
            };
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = httpCode;
    
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
    

    Then you "decorate" your controller actions with this attribute:

    [HandleManyErrors]
    public ActionResult DoSomethingBuggy ()
    {
        // ...
    }
    
    0 讨论(0)
  • 2020-12-05 08:23

    If you're using ASP.NET MVC, you're more than likely to use IIS, so why don't you just set up IIS to use your custom 401 error page for that Web Application / Virtual Directory?

    0 讨论(0)
  • 2020-12-05 08:30

    I managed to solve this in a very simple way. I wanted to show a custom page for logged-in users ("you have no permission bla bla...") and redirect unauthenticated users to the login page (the default behaviour). So I implemented a custom AuthorizeAttribute (say CustomAuthorizeAttribute) with the HandleUnauthorizedRequest method overwritten in a way that if the user is authenticated I set the Result property of the filterContext argument with a ViewResult (in the Shared folder) called AccessDenied.aspx

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        else
        {
            filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
        }
    }
    

    Then you have to use this new attribute instead. Regards.

    0 讨论(0)
  • 2020-12-05 08:43

    In one of my project, I use the code from uvita.

    I have ASP.NET MVC2 and I use Active Directory authentication without login page. I have a NoAuth.aspx page that use site master page, integrate the web application layout.

    This is the web.config.

    <system.web>
        <authentication mode="Windows" />
        <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
           <providers>
              <clear />
              <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider"
              applicationName="/" />
          </providers>
        </roleManager>
    </system.web>
    

    The new class CustomAutorizeAttribute

    using System.Web.Mvc;
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
            else
            {
               filterContext.Result = new ViewResult { ViewName = "NoAuth"};
            }
        }
    }
    

    and the controller

    [CustomAuthorize(Roles = "ADRole")]
    public class HomeController : Controller
    {
        public HomeController()
        {
        }
    }
    
    0 讨论(0)
提交回复
热议问题