【问题标题】:ASP.NET MVC redirect to an access denied page using a custom role providerASP.NET MVC 使用自定义角色提供程序重定向到拒绝访问页面
【发布时间】:2010-11-19 18:16:27
【问题描述】:

我正在创建一个自定义角色提供程序,并在我的控制器中设置了一个指定角色的 Authorize 属性,它工作得很好,如下所示:

[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...

但是当用户无权访问此控制器时,他会被重定向到登录页面。 如何将他重定向到“AcessDenied.aspx”页面?

【问题讨论】:

    标签: asp.net-mvc asp.net-membership roleprovider


    【解决方案1】:
    [AccessDeniedAuthorize(Roles="SuperAdmin")]
    public class SuperAdminController : Controller
    

    AccessDeniedAuthorizeAttribute.cs:

    public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
    
            if(filterContext.Result is HttpUnauthorizedResult)
            {
                filterContext.Result = new RedirectResult("~/AcessDenied.aspx");
            }
        }
    }
    

    【讨论】:

    • 如果用户登录并尝试访问该页面,他们将被重定向到 AccessDenied 页面。好的。但是,如果用户没有登录,他们将被重定向到 AccessDenied 页面。坏的。在这种情况下,他们应该被重定向到登录页面。
    • 如果您希望页面在用户不再在的情况下正常重定向,在 base.OnAuthorization() 方法调用之后,在其余代码周围添加一个 if 语句来检查是否Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated。这样,除非用户未通过身份验证,否则用户将被定向到 AccessDenied 页面......在这种情况下,它将执行默认操作(重定向到登录页面)
    • 这个类放在哪里?在控制器中?
    • 工作正常,但我认为 Frinavale 点是好的和有效的。 (y)
    • MVC: AcessDenied.aspx ?不是cshtml?
    【解决方案2】:

    这是我的解决方案,基于 eu-ge-ne 的回答。 如果用户未登录,我的会正确地将用户重定向到登录页面,但如果他们已登录但未经授权查看该页面,则会重定向到拒绝访问页面。

    [AccessDeniedAuthorize(Roles="SuperAdmin")]
    public class SuperAdminController : Controller
    

    AccessDeniedAuthorizeAttribute.cs:

    public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = new RedirectResult("~/Account/Logon");
                return;
            }
    
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                filterContext.Result = new RedirectResult("~/Account/Denied");
            }
        }
    }
    

    AccountController.cs:

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

    Views/Account/Denied.cshtml:(Razor 语法)

    @{
        ViewBag.Title = "Access Denied";
    }
    
    <h2>@ViewBag.Title</h2>
    
    Sorry, but you don't have access to that page.
    

    【讨论】:

    • 任何AccessDeniedForMobileOrTabletAttribute ?
    【解决方案3】:

    看看tvanfossonAnswer from this very similar question,这就是我正在做的事情(感谢tvanfosson),所以现在我只需要说:

    [MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
    public class SuperAdminController : Controller
    ...
    

    如果用户不在角色中,他们将获得 ViewName 指定的视图。

    【讨论】:

      【解决方案4】:

      通过避免对登录页面进行硬编码并可选地在属性中设置访问被拒绝视图,对马特的回答略有改进:

      public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
      {
          public string AccessDeniedViewName { get; set; }
      
          public override void OnAuthorization(AuthorizationContext filterContext)
          {
              base.OnAuthorization(filterContext);
      
              if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
                  filterContext.Result is HttpUnauthorizedResult)
              {
                  if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
                      AccessDeniedViewName = "~/Account/AccessDenied";
      
                  filterContext.Result = new RedirectResult(AccessDeniedViewName);
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        重定向并不总是最好的解决方案

        使用标准 http 代码 403:

        return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
        

        【讨论】:

          【解决方案6】:

          我有类似的问题。无论我担任什么角色,我总是被重定向到登录页面而不是 AccessDenied。 修复非常简单,但可能并非在所有情况下都有效。事实证明,我在 Startup.cs 中这两行的顺序错误:

          app.UseAuthentication();
          app.UseAuthorization();
          

          确保 app.UseAuthentication();是之前 app.UseAuthorization();

          换句话说,问“你是谁?”首先,然后是“你可以在这里吗?”,而不是相反。

          【讨论】:

            【解决方案7】:
            public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
                {
                    public override void OnAuthorization(AuthorizationContext filterContext)
                    {
                        base.OnAuthorization(filterContext);
            
                        if (filterContext.Result is HttpUnauthorizedResult && WebSecurity.IsAuthenticated)
                        {
                            filterContext.Result = new RedirectResult("~/Account/AccessDenied");
                        }
                    }
                }
            

            【讨论】:

              【解决方案8】:

              我建立在 Vic 的回答基础上,允许我为每个应用程序区域提供不同的拒绝访问页面。通过返回 RedirectToRouteResult 来实现,而不是重定向到相对于应用程序根目录的 URL,而是重定向到当前区域的控制器和操作:

              public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
              {
                  public string AccessDeniedController { get; set; }
                  public string AccessDeniedAction { get; set; }
              
                  public override void OnAuthorization(AuthorizationContext filterContext)
                  {
                      base.OnAuthorization(filterContext);
              
                      if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
                          filterContext.Result is HttpUnauthorizedResult)
                      {
                          if (String.IsNullOrWhiteSpace(AccessDeniedController) || String.IsNullOrWhiteSpace(AccessDeniedAction))
                          {
                              AccessDeniedController = "Home";
                              AccessDeniedAction = "AccessDenied";
                          }
              
                          filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = AccessDeniedController, Action = AccessDeniedAction }));
                      }
                  }
              }
              

              【讨论】:

                【解决方案9】:

                只是对 Vic Alcazar 的一个小更新, 在重定向中添加了请求 url 的详细信息 这样就可以记录访问被拒绝的详细信息以及由谁来记录

                public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
                {
                    public string AccessDeniedViewName { get; set; }
                
                    public override void OnAuthorization(AuthorizationContext filterContext)
                    {
                        base.OnAuthorization(filterContext);
                
                        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
                            filterContext.Result is HttpUnauthorizedResult)
                        {
                            if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
                                AccessDeniedViewName = "~/Account/AccessDenied";
                
                            var requestUrl = filterContext.HttpContext.Request.Url;
                
                            filterContext.Result = new RedirectResult(String.Format("{0}?RequestUrl={1}", AccessDeniedViewName, requestUrl));
                        }
                    }
                }
                

                【讨论】:

                  猜你喜欢
                  • 2016-11-24
                  • 2013-01-22
                  • 1970-01-01
                  • 2014-10-15
                  • 1970-01-01
                  • 2017-06-15
                  • 2015-05-18
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多