【问题标题】:Update rate limits at runtime in WebApiThrottle is not workingWebApiThrottle 运行时的更新速率限制不起作用
【发布时间】:2017-07-03 21:49:24
【问题描述】:

我在 ASP.NET MVC 中有一个 WebApi,我需要控制访问限制,此外我还需要在运行时更改限制的值。 我在这个网站上实现了这个例子WebApiThrottle运行时更新速率限制部分)

这是我的 WebApiConfig 中的代码:

//trace provider
var traceWriter = new SystemDiagnosticsTraceWriter()
{
    IsVerbose = true
};
config.Services.Replace(typeof(ITraceWriter), traceWriter);
config.EnableSystemDiagnosticsTracing();

//Web API throttling handler
config.MessageHandlers.Add(new ThrottlingHandler(
    policy: new ThrottlePolicy(perMinute: 3, perHour: 30, perDay: 35, perWeek: 3000)
    {
        //scope to IPs
        IpThrottling = true,
        //scope to clients
        ClientThrottling = true,
        ClientRules = new Dictionary<string, RateLimits>
        {
            { "client-key-1", new RateLimits { PerMinute = 1, PerHour = 60 } }
        },

        //scope to endpoints
        EndpointThrottling = true
    },

    //replace with PolicyMemoryCacheRepository for Owin self-host
    policyRepository: new PolicyCacheRepository(),

    //replace with MemoryCacheRepository for Owin self-host
    repository: new CacheRepository(),

    logger: new TracingThrottleLogger(traceWriter)));

我定义了每分钟三个请求,就像默认值一样,每分钟一个请求到客户端,密钥为“client-key-1”。 但是当我使用 PostMan 进行测试时(我正在传递值为 client-key-1 的授权令牌),我注意到只使用了默认配置,因为只有在三个请求之后我才收到消息:

而且,即使我更新了速率限制,使用函数:

public void UpdateRateLimits()
{
    //init policy repo
    var policyRepository = new PolicyCacheRepository();

    //get policy object from cache
    var policy = policyRepository.FirstOrDefault(ThrottleManager.GetPolicyKey());

    //update client rate limits
    policy.ClientRules["client-key-1"] =
        new RateLimits { PerMinute = 20 };

    //apply policy updates
    ThrottleManager.UpdatePolicy(policy, policyRepository);

}

消息“超出 API 调用配额!每分钟最多允许 3 个。”继续出现。

有人遇到过这个问题吗?

【问题讨论】:

  • 什么是ThrottlePolicy?那是 asp.net 的一部分吗?
  • @spender 它来自 WebApiThrottle,我在其中配置 API 的速率限制。

标签: c# asp.net asp.net-web-api


【解决方案1】:

在尝试了很多事情之后,我可以配置我的班级以考虑我的自定义速率限制。

我所做的是:

1) 我创建了一个类来覆盖 SetIdentity 方法,就像在站点 WebApiThrottle 中一样:

public class CustomThrottlingHandler : ThrottlingHandler
{
    public CustomThrottlingHandler(ThrottlePolicy policy, IPolicyRepository policyRepository, IThrottleRepository repository, IThrottleLogger logger, IIpAddressParser ipAddressParser = null)
        : base(policy, policyRepository, repository, logger, ipAddressParser)
    {

    }

    protected override RequestIdentity SetIdentity(HttpRequestMessage request)
    {
        return new RequestIdentity
        {
            ClientKey = request.Headers.Contains("my-header") ? request.Headers.GetValues("my-header").First() : "anon",
            ClientIp = base.GetClientIp(request).ToString(),
            Endpoint = request.RequestUri.AbsolutePath.ToLowerInvariant()
        };
    }
}

2) 我更改了 MessageHandlers.Add 以使用我的自定义类 (CustomThrottlingHandler) 而不是 ThrottlingHandler 类:

public static void Register(HttpConfiguration config)
{
    //trace provider
    var traceWriter = new SystemDiagnosticsTraceWriter()
    {
        IsVerbose = true
    };
    config.Services.Replace(typeof(ITraceWriter), traceWriter);
    config.EnableSystemDiagnosticsTracing();

    //Web API throttling handler
    config.MessageHandlers.Add(new CustomThrottlingHandler(
        policy: new ThrottlePolicy(perMinute: 20, perHour: 30, perDay: 35, perWeek: 3000)
        {
            //scope to IPs
            IpThrottling = true,

            //scope to clients
            ClientThrottling = true,
            ClientRules = new Dictionary<string, RateLimits>
            { 
                { "api-client-key-1", new RateLimits { PerMinute = 60, PerHour = 600 } },
                { "api-client-key-2", new RateLimits { PerDay = 5000 } }
            },

            //scope to endpoints
            EndpointThrottling = true
        },

        //replace with PolicyMemoryCacheRepository for Owin self-host
        policyRepository: new PolicyCacheRepository(),

        //replace with MemoryCacheRepository for Owin self-host
        repository: new CacheRepository(),

        logger: new TracingThrottleLogger(traceWriter)));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2019-09-25
    • 2016-10-03
    • 1970-01-01
    • 2011-07-04
    • 2016-04-26
    相关资源
    最近更新 更多