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

时间:2014-02-27 16:27:52

标签: 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>

我也在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 }
    );

这还够吗?

5 个答案:

答案 0 :(得分:23)

经过一番研究后,我认为这个问题最简单的答案就是创建自定义授权,非常类似于jbbi的那个(但是自从&#34;新的HttpUnauthorizedResult()&#34以来,它没有工作。 ;是internaly自动重定向到登录 - 至少在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" }));
        }
    }
}

,其用法与默认授权:

相同
[CustomAuthorize(Roles = "Administrator")]

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

public ActionResult AccessDenied()
{
    Response.StatusCode = 403;
    return View();
}

这很简单,有效,甚至我(.net mvc rookie)也明白这一点。

注意:它与401代码的工作方式不同 - 它将始终接管401并将internaly重定向到登录。但就我而言,根据定义,403也适合。

答案 1 :(得分:16)

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

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);
        }
    }

}

然后在Controller或Action上应用如下:

[CustomAuthorize(Roles = "Admin")]

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

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

答案 2 :(得分:4)

处理此问题的最佳方法可能是创建一个额外的操作过滤器,如果用户不属于指定的角色,则会将用户重定向到指定的错误页面。 因此,此方法将应用两个过滤器:[授权](没有角色)来保护未经身份验证的用户并将其重定向到登录页面。以及具有角色的自定义属性。代码SIMILAR(未经测试):

public class RoleFilterAttribute : ActionFilterAttribute
{
    public string Role { get; set; }
    public override void OnActionExecuting(ActionExecutingContext ctx)
    {
        // Assume that we have user identity because Authorize is also
        // applied
        var user = ctx.HttpContext.User;
        if (!user.IsInRole(Role))
        {
            ctx.Result = new RedirectResult("url_needed_here");
        }
    }
}

将[Authorize]和[RoleFilter]同时应用于操作...

希望这有帮助!

答案 3 :(得分:2)

我认为您应该创建自己的授权过滤器属性,该属性继承默认的授权过滤器

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

答案 4 :(得分:0)

要重定向未经授权的页面访问Asp.net C#到自定义视图

  1. 在页面加载时,将其添加到login.aspx.cs
     protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                
                txtUsername.Focus();
                if (!IsPostBack)
                {
                    if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
                    {
                        Response.Redirect("UnauthorizedAccess.aspx", false);
                        return;
                    }                   
                    Session.Clear();
                    Session.Abandon();

                }                
            }
            catch (Exception ex)
            {
                this.errLogin.Text = ex.Message;                
            }
        }

2)创建UnauthorizedAccess.aspx

    <h1>Unauthorized</h1>

        
            <p>Sorry, you are not authorized to access this page</p>
        
           <asp:LinkButton ID="lnkhome" runat="server" CssClass="btn btn-success1" OnClick="lnkhome_Click"
               CausesValidation="false"><span class="fa fa-home"/> Back to Home</asp:LinkButton>
相关问题