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

Posted

技术标签:

【中文标题】当用户在 asp.net mvc3 中未授权时重定向到另一个页面【英文标题】:Redirect to another page when user is not authorized in asp.net mvc3 【发布时间】:2012-06-11 07:10:21 【问题描述】:

我读过

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://***.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 页面。

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

【问题讨论】:

【参考方案1】:

默认Authorize 属性的行为方式是,当用户未通过身份验证已通过身份验证但未授权时,它会将状态代码设置为 401(未经授权)。当过滤器将状态代码设置为 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 属性而不是内置属性。

【讨论】:

点赞并接受!备注一:必须使用protected override void HandleUnauthorizedRequest( AuthorizationContext filterContext ) 覆盖方法,否则无效 这是我一直遇到的一个解决方案,但这真的仍然是唯一的方法吗?必须重新创建 [Authorize] 过滤器来更改路径似乎有点过头了。【参考方案2】:

我喜欢马克的回答, 但我不想更改所有操作属性 从 [Authorize] 到 [CustomAuthorize]

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

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

        ViewBag.ReturnUrl = returnUrl;

        return View();
    

【讨论】:

但是在这种情况下,如果您已经登录并转到登录页面,您将看到/error/accessDenied 而不是/account/login,对吗?如果您不想将[Authorize] 更改为[CustomAuthorize],您可以随时将其命名为YourBrand.YourProject.Security.AuthorizeAttribute,然后仅引用YourBrand.YourProject.Security 或其他内容 我喜欢这个解决方案,但如果他们已经通过身份验证但未获得授权,那么我将重定向到每个人都获得授权的非错误主页,并包含一个可选的 ViewBag 状态消息,上面写着类似$"您无权查看 returnUrl"。【参考方案3】:

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

【讨论】:

【参考方案4】:

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

    

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

以上是关于当用户在 asp.net mvc3 中未授权时重定向到另一个页面的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core 中未经授权时重定向到登录

MVC 3 ASP.NET 角色-授权属性

在 Asp.Net Core 中使用 Swagger 在请求中未发送授权承载令牌

C# asp.net MVC3 中的日历控件

通过 Auth0 React 和 ASP.net 核心授权然后使用 JWT 令牌

如何使用 ASP.NET MVC3 编辑嵌套模型