ASP.NET MVC 5中的自定义授权过滤器?

问题描述:

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

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

+0

所以,你确实希望'[AllowAnonymous]',但只限于每次访问有限的时间,站点范围内。 –

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

public class CustomAuthAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 

     //your code here 
    } 
} 

下面我列出一些例子,在哪里以及为何使用AuthorizeAttribute

1,检查授权和限制访问行为与[CustomAuthAttribute]

然后装点你的控制器/行动。

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 
    { 
    } 

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

您可以实现自定义授权的时间这样的量有限时,允许匿名浏览:

public class AuthorizeAttributeWithAnonTimeoutAttribute : 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. 
        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 AuthorizeAttributeWithAnonTimeoutAttribute 
     { 
      // 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. 
[AuthorizeAttributeWithAnonTimeout(AnonymousMinutesTimeout = 10)] 
public class YourController 
{ 
} 

请注意,这种做法不保证匿名超时。只要他愿意,黑客可以克服它并匿名浏览。浏览器工具允许删除cookie,因此很容易以新的超时启动。

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