当用户未在asp.net mvc3中授权时,重定向到另一个页面

时间:2012-06-07 08:28:19

标签: c# asp.net asp.net-mvc asp.net-mvc-3

我读过

How to easily redirect if not authenticated in MVC 3?Redirect to AccessDenied page when user is not authorized但是答案中的链接(表示http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/)不起作用。

我把

[Authorize(Users = "test")]
    public class RestrictedPageController: Controller
    {

        public ActionResult Index()
        {
           return View();
        }

 ....
    }

在我的web.config中,我已经

 <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="2880" />
 </authentication>

相应地使用https://stackoverflow.com/a/6770583/998696

但是当我想访问/RestrictedPage/Index时,它必须将我重定向到其他页面(来自其他控制器)。而不是这个,错误看起来像:

Server Error in '/Project' Application.

The view 'LogOn' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Account/LogOn.aspx
~/Views/Account/LogOn.ascx
~/Views/Shared/LogOn.aspx
~/Views/Shared/LogOn.ascx
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml

登录前,Logon页面表单正确显示,但访问/RestrictedPage/Index页面时出现上述错误。我可以使用授权访问RestrictedPage页面的用户登录。

我的错误在哪里以及设置重定向如何?

5 个答案:

答案 0 :(得分:55)

默认Authorize属性的行为方式是,当用户未经过身份验证已经过身份验证但未经过授权时,它会将状态代码设置为< strong> 401(UnAuthorized)。当过滤器将状态代码设置为 401 时,ASP.NET框架会检查网站是否启用了表单身份验证,如果是,则重定向到那里设置的loginUrl参数。

如果要更改该行为,则表示要将用户重定向到AccessDenied控制器,如果用户已通过身份验证但未获得授权,则必须扩展Authorize属性并覆盖{{ 1}}方法。

对于前。

HandleUnauthorizedRequest

您可以根据需要覆盖public class CustomAuthorize: AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.Result = new HttpUnauthorizedResult(); } else { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "AccessDenied" })); } } } ,然后必须标记控制器操作以使用HandleUnauthorizedRequest属性而不是内置属性。

答案 1 :(得分:3)

我喜欢马克的答案,
但我不想改变我的所有动作属性 从[授权]到[CustomAuthorize]

我在Login()上编辑AccountController操作 并在显示视图之前检查Request.IsAuthenticated 我想,如果经过身份验证的用户转到/Account/Logon,则 我将重定向到/Error/AccessDenied

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        if (Request.IsAuthenticated)
        {
            return RedirectToAction("AccessDenied", "Error");
        }

        ViewBag.ReturnUrl = returnUrl;

        return View();
    }

答案 2 :(得分:2)

放置“/ Account / LogOn”而不是“〜/ Account / LogOn”

答案 3 :(得分:1)

是的,正如您在web.config

中提到的那样
<forms loginUrl="~/Account/LogOn" timeout="2880" />

重定向正在寻找Account控制器和LogOn actionresult。如果您想重定向您的网页,请更改该网页而不是帐户和登录

答案 4 :(得分:1)

由于我不想覆盖AuthorizeAttribute我使用了过滤器

public class RedirectFilter : ActionFilterAttribute
{
   public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        if (!IsAuthorized(filterContext))
        {
            filterContext.Result =
                new RedirectToRouteResult(new RouteValueDictionary(new {controller = "AccessDenied"}));
        }
    }

    private bool IsAuthorized(ActionExecutingContext filterContext)
    {
        var descriptor = filterContext.ActionDescriptor;
        var authorizeAttr = descriptor.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute;

        if (authorizeAttr != null)
        {
            if(!authorizeAttr.Users.Contains(filterContext.HttpContext.User.ToString()))
            return false;
        }
        return true;

    }
}