将MVC中的未授权页面访问重定向到自定义视图

use*_*418 17 asp.net-mvc authorization unauthorized

我有一个MVC网站,其中访问基于各种角色.一旦用户登录系统,他们就可以看到导航到他们被授权的页面.但是,某些用户可能仍尝试使用直接URL访问页面.如果是这样,系统会自动将它们重定向到登录页面.而不是登录页面我想将它们重定向到另一个视图(未授权).

Web.Config具有以下条目:

    <customErrors mode="On">
      <error statusCode="401" redirect="~/Home/Unauthorized" />
      <error statusCode="404" redirect="~/Home/PageNotFound" />
    </customErrors>
    <authentication mode="Forms">
<forms name="Development" loginUrl="~/Account/Login" cookieless="UseCookies" timeout="120"></forms>
    </authentication>
Run Code Online (Sandbox Code Playgroud)

我也在Global.asax.cs中注册了这些路由.

routes.MapRoute(
    name: "Unauthorized",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Unauthorized", id = UrlParameter.Optional }
   );


routes.MapRoute(
    name: "PageNotFound",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "PageNotFound", id = UrlParameter.Optional }
    );
Run Code Online (Sandbox Code Playgroud)

它够了吗?

The*_*sek 31

经过一些研究后,我认为这个问题的最简单答案就是创建自定义授权,非常类似于jbbi的那个(但是由于"新的HttpUnauthorizedResult()"是内部自动重定向到登录,因此一个没有用 - 至少在mvc 5与身份)

public class CustomAuthorize : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            //if not logged, it will work as normal Authorize and redirect to the Login
            base.HandleUnauthorizedRequest(filterContext);

        }
        else
        {
            //logged and wihout the role to access it - redirect to the custom controller action
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法与默认授权相同:

[CustomAuthorize(Roles = "Administrator")]
Run Code Online (Sandbox Code Playgroud)

然后,只是为了做正确的事情,不要忘记发送错误页面的Http代码.在控制器中喜欢这样.

public ActionResult AccessDenied()
{
    Response.StatusCode = 403;
    return View();
}
Run Code Online (Sandbox Code Playgroud)

它很容易,它可以工作,甚至我(.net mvc rookie)也明白这一点.

注意:对于401代码它不起作用 - 它将始终接管401并且internaly将其重定向到登录.但在我的情况下,根据定义,403也适合.

  • 确保使用 System.Web.Mvc 命名空间而不是 System.Web.Http。他们都有 HandleUnauthorizedRequest 方法 (2认同)

use*_*418 18

通过以下更改,它正在运行

public class CustomAuthorize : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        //filterContext.Result = new HttpUnauthorizedResult(); // Try this but i'm not sure
          filterContext.Result = new RedirectResult("~/Home/Unauthorized");
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (this.AuthorizeCore(filterContext.HttpContext))
        {
            base.OnAuthorization(filterContext);
        }
        else
        {
            this.HandleUnauthorizedRequest(filterContext);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后应用Controller或Action如下:

[CustomAuthorize(Roles = "Admin")]
Run Code Online (Sandbox Code Playgroud)

通过上述方法,我需要重新访问所有控制器/操作并更改授权属性!还需要进行一些测试.

我仍然不确定为什么Web.Config路由不能在MVC文档中解释.可能是MVC 4中发生了变化!