【问题标题】:Custom Authorization filter in ASP.NET MVC 5?ASP.NET MVC 5 中的自定义授权过滤器?
【发布时间】:2017-04-08 05:59:02
【问题描述】:

在 ASP.NET MVC 5 中,我们可以使用[Authorize] 属性来检查授权并限制对某些操作\页面的访问。 我想知道如何修改这个属性 - 一段时间后应该检查授权? 例如,让未经授权的用户在 10 分钟内查看该页面,然后阻止访问

已更新:我的问题似乎不清楚,所以我将问题加粗。我需要计算每个未经授权的用户在网站上花费的时间,然后在 N 分钟后阻止他。

【问题讨论】:

  • 所以你确实想[AllowAnonymous],但每次访问的时间有限,站点范围内。

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


【解决方案1】:

您可以实现自定义授权,以在有限的时间内允许匿名浏览,如下所示:

public class AuthorizeWithAnonymousTimeoutAttribute : AuthorizeAttribute
{
    public int? AnonymousMinutesTimeout { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        // Let default handling occurs
        base.OnAuthorization(filterContext);

        // If result is set, authorization has already been denied,
        // nothing more to do.
        if (filterContext.Result as HttpUnauthorizedResult != null)
            return;

        var isAnonAllowed = filterContext.ActionDescriptor.IsDefined(
                typeof(AllowAnonymousAttribute), true) || 
            filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
                typeof(AllowAnonymousAttribute), true);
        if (isAnonAllowed && AnonymousMinutesTimeout.HasValue &&
            // Not authorized
            !AuthorizeCore(filterContext.HttpContext))
        {
            const string visitStartCookieName = "visitStartCookie";
            const string visitStartDateFormat = "yyyyMMddhhmmss";
            var visitStartCookie = filterContext.HttpContext.Request
                .Cookies[visitStartCookieName];
            var now = DateTime.UtcNow;
            DateTime visitStartDate;
            var visitStartCookieValid = visitStartCookie != null &&
                DateTime.TryParseExact(visitStartCookie.Value,
                    visitStartDateFormat, null, DateTimeStyles.AssumeUniversal,
                    out visitStartDate);
            if (!visitStartCookieValid)
            {
                visitStartDate = now;
                filterContext.HttpContext.Response.Cookies.Add(
                    // Session cookie. (Need to set an expiry date if
                    // a "permanent" cookie is wished instead.)
                    new HttpCookie
                    {
                        Name = "visitStartCookie",
                        Value = now.ToString(visitStartDateFormat)
                    });
            }
            if (visitStartDate.AddMinutes(AnonymousMinutesTimeout.Value) < now)
            {
                // Anonymous visit timed out
                HandleUnauthorizedRequest(filterContext);
                return;
            }
        }
    }
}

然后,如果它适合您,请将其用作全局过滤器,如下所示:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(
        new AuthorizeWithAnonymousTimeoutAttribute
        {
            // By example, 10 minutes
            AnonymousMinutesTimeout = 10
        });
    // Your other filters
    ...
}

别忘了用AllowAnonymousAttribute装饰你的控制器或动作:

[AllowAnonymous]
public class YourController
{
}

或者

public class YourController
{
    [AllowAnonymous]
    public ActionResult YourAction()
    {
    }
}

如果全局定义不适合您,您也可以将自定义授权属性直接放在控制器或操作上:

// By example, 10 minutes anonymous browsing allowed.
[AuthorizeWithAnonymousTimeout(AnonymousMinutesTimeout = 10)]
public class YourController
{
}

请注意,此实现不保证匿名超时。只要他愿意,黑客就可以克服它并匿名浏览。浏览器工具允许删除 cookie,因此很容易从新的超时开始。
我的示例还只是设置了一个会话 cookie,它会通过关闭/重新打开浏览器而消失。当然,使用其他浏览器或设备可以再使用 10 分钟。

确保匿名超时非常困难,因为您的用户是匿名的。您可以尝试从他们的技术特征中识别您的匿名用户,然后在服务器端跟踪他们的超时时间。
但是您可能会遇到很多问题:企业用户使用相同的 IP 地址浏览,或者因为没有单一的 Internet 连接而在不同的 IP 之间切换,...​​

【讨论】:

    【解决方案2】:

    这样的?创建您自己的属性并用您自己的代码覆盖默认值。

    public class CustomAuthAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
    
            //your code here
        }
    }
    

    然后用 [CustomAuthAttribute] 装饰你的控制器/动作

    【讨论】:

      【解决方案3】:

      下面我列出了一些示例,说明在哪里以及为什么要使用 AuthorizeAttribute

      1.检查授权并限制对操作的访问。

      Example :
      
           // Restrict unauthorized access:       
           [Authorize]  
           public ActionResult YourActionView()  
           {  
             return View();  
           }  
      
      
          // Restrict by user:       
          [Authorize(Users = "prashant,lua")]  
              public ActionResult YourActionView()  
              {  
                 return View();  
              }  
      
          // Restrict by role:
          [Authorize(Roles="Administrators")]
           public ActionResult YourActionView()  
              {  
                 return View();  
              }  
      

      2.检查授权并限制对控制器的访问。

          // Restrict unauthorized access:       
          [Authorize]  
          public class ValuesController : ApiController
          {
          }
      
          // Restrict by user:
          [Authorize(Users="Prashant,Lua")]
          public class ValuesController : ApiController
          {
          }
      
         // Restrict by role:
         [Authorize(Roles="Administrators")]
         public class ValuesController : ApiController
         {
         }
      

      【讨论】:

        【解决方案4】:

        我认为 Authorize 属性旨在促进授权过程。如果您想允许匿名用户查看您的站点并在一段时间后阻止访问,请考虑一些客户端脚本。

        【讨论】:

          猜你喜欢
          • 2010-11-01
          • 2013-12-14
          • 2018-12-11
          • 2013-10-31
          • 2010-09-30
          • 1970-01-01
          • 2019-03-10
          • 1970-01-01
          相关资源
          最近更新 更多