23

我读了

如果未在 MVC 3 中进行身份验证,如何轻松重定向?当用户未获得授权但来自答案的链接(表示http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/)不起作用时 重定向到 AccessDenied 页面。

我放

[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页面的用户登录。

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

4

5 回答 5

63

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

如果您想更改该行为,AccessDenied如果用户已通过身份验证但未授权,则您希望将用户重定向到控制器,那么您必须扩展Authorize属性并覆盖该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,然后您必须标记控制器操作以使用该CustomAuthorize属性而不是内置属性。

于 2012-06-07T09:08:53.627 回答
6

我喜欢 Mark's Answer,
但我不想将我的所有操作属性
从 [Authorize] 更改为 [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();
    }
于 2015-07-22T07:31:36.830 回答
2

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

于 2012-06-07T09:36:31.497 回答
2

因为我不想覆盖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;

    }
}
于 2017-03-10T08:08:11.757 回答
1

是的,正如您在 web.config 中提到的那样是正确的

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

重定向正在寻找帐户控制器和登录操作结果。如果你想重定向你的页面,改变那里而不是帐户和登录

于 2012-06-07T08:41:01.573 回答