Azure中的ASP.NET Web API:自定义身份验证过滤器以防止暴力?

Azure中的ASP.NET Web API:自定义身份验证过滤器以防止暴力?,asp.net,asp.net-web-api,asp.net-identity,asp.net-web-api2,asp.net-authorization,Asp.net,Asp.net Web Api,Asp.net Identity,Asp.net Web Api2,Asp.net Authorization,我从VS2013 SPA模板(web api 2.2)中获得了一个网站,它利用了ASP.NET Identity 2.1,一切都运行得非常好。我的控制器方法如下所示: [Authorize] public Api.Models.Widget Get(int widgetId) { var requestingUserId = Int32.Parse(Microsoft.AspNet.Identity.IdentityExtensions.GetUserId(Use

我从VS2013 SPA模板(web api 2.2)中获得了一个网站,它利用了ASP.NET Identity 2.1,一切都运行得非常好。我的控制器方法如下所示:

    [Authorize]
    public Api.Models.Widget Get(int widgetId)
    {
    var requestingUserId = Int32.Parse(Microsoft.AspNet.Identity.IdentityExtensions.GetUserId(User.Identity));
    ...

}
它按预期工作:

  • 未经授权的用户无权访问
  • 在授权用户进入后,我可以获取他们的用户ID
但是我现在想修改应用程序以防止过多的API请求。我计划检查特定的用户ID是否在特定的时间范围内发出了特定数量的请求。我正在寻找最佳地点的建议。

我不想在每个控制器中重复这种逻辑,而且似乎动作过滤器可能是最好的地方。但由于这需要读取userid,并且我不确定过滤器的顺序是否得到保证,因此,如果可能的话,派生已经被调用以进行授权的过滤器并添加我的额外逻辑也是有意义的

我想知道是否有人能举一个做类似事情的例子?它似乎不是“授权”,而是在一个自定义的身份验证过滤器中,我不确定如何将其绑定在一起


感谢您的建议…

有几个过滤器选项:

授权过滤器 就是否要 执行操作方法,例如执行身份验证或 正在验证请求的属性

例如:

public class WebApiAuthorizeAttribute : AuthorizeAttribute 
{
    public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        base.OnAuthorization(actionContext);

        Guid userId = new Guid(HttpContext.Current.User.Identity.GetUserId());

        // ...here your validation logic 
    }
}
动作过滤器 包装动作方法的执行。这个过滤器 可以执行附加处理,例如向 操作方法、检查返回值或取消执行 动作法

为了尽量减少对服务器的影响,您可以在用户浏览器中缓存任何http get请求一段预定义的时间,如果用户在该预定义时间内请求相同的URL,则将从浏览器缓存而不是服务器加载响应。 由于OutputCache属性不适用于Web API,您可以使用或实现自己的操作筛选器属性进行缓存:

public class CacheFilterAttribute : ActionFilterAttribute
{
    /// <summary>
    /// Gets or sets the cache duration in seconds. The default is 10 seconds.
    /// </summary>
    /// <value>The cache duration in seconds.</value>
    public int Duration
    {
        get;
        set;
    }

    public CacheFilterAttribute()
    {
        Duration = 10;
    }

    public override void OnActionExecuted(FilterExecutedContext filterContext)
    {
        if (Duration <= 0) return;

        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
        TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);

        cache.SetCacheability(HttpCacheability.Public);
        cache.SetExpires(DateTime.Now.Add(cacheDuration));
        cache.SetMaxAge(cacheDuration);
        cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
    }
}
公共类CacheFilterAttribute:ActionFilterAttribute
{
/// 
///获取或设置缓存持续时间(秒)。默认值为10秒。
/// 
///缓存持续时间(秒)。
公共整数持续时间
{
得到;
设置
}
公共缓存过滤器属性()
{
持续时间=10;
}
已执行操作(FilterExecutedContext filterContext)上的公共重写无效
{

如果(Duration我认为您正在关注的是一个过滤器,它将限制您的用户发出的请求,因此您应该检查webapitrottle


这应该符合您的目标,或者您可以根据需要查看源代码对其进行自定义。

“此存储应该尽可能轻。因此,使用NoSQL db可能是一个好方法。”是的,打得好。因为这是在Azure中,所以我计划使用Azure表存储进行此操作。感谢您的帮助!@BenjiFB我同意这种细粒度会话状态跟踪对于SQL Server来说不是一项工作,但我不确定Azure表存储是否也是。我的预感是,Azure Redis缓存在SQL Server中的性能将提高一个数量级这种情况。我觉得这个节流计划正在变成一个小型项目,只是为了满足一种感知需求。请记住,真正恶意的用户可能会淹没您的系统,并导致它挂起那些进程外会话频率检查,特别是在不使用异步等待编码实践的情况下。