You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM中配置IP白名单豁免的限流策略问题

问题分析

你的现有策略逻辑完全颠倒了:

  • 先执行rate-limit-by-key,所有请求都会被限流统计
  • 之后的<ip-filter action="allow">会直接拒绝所有非白名单IP,导致这类请求根本不会触发限流(直接被阻断),而白名单IP会完整经过限流规则,这和你“白名单豁免限流”的需求完全相反。
最优实现方案

使用APIM的<choose>条件策略,仅对非白名单IP应用限流规则,同时保留白名单IP的无限制访问权限。如果不需要拒绝非白名单IP,无需保留<ip-filter action="allow">(它会直接阻断非白名单请求)。

修正后的策略代码

<set-backend-service id="apim-generated-policy" backend-id="name-of-my-function-app" />
<choose>
    <!-- 对非白名单IP应用限流 -->
    <when condition="@(!(
        // 单个IP判断
        context.Request.IpAddress == "10.20.30.40" ||
        // IP段判断:10.0.0.0-10.0.0.254
        IPAddress.Parse(context.Request.IpAddress).IsInRange("10.0.0.0", "10.0.0.254") ||
        // IP段判断:10.1.0.0-10.1.0.254
        IPAddress.Parse(context.Request.IpAddress).IsInRange("10.1.0.0", "10.1.0.254") ||
        // IP段判断:10.2.0.0-10.2.0.254
        IPAddress.Parse(context.Request.IpAddress).IsInRange("10.2.0.0", "10.2.0.254")
    ))">
        <rate-limit-by-key 
            calls="60" 
            renewal-period="60" 
            counter-key="@(context.Request.IpAddress)" 
            increment-condition="@(context.Response.StatusCode == 204 ^ context.Response.StatusCode == 404)" 
            remaining-calls-variable-name="remainingCallsPerIP" />
    </when>
    <!-- 白名单IP不执行任何限流 -->
    <otherwise />
</choose>

关键说明

  1. 条件判断逻辑:通过!()取反,仅当请求IP不在白名单范围内时,才触发限流规则
  2. IP段校验:使用APIM内置的IsInRange方法快速判断IP是否属于指定网段
  3. 保留原有限流规则:你的rate-limit-by-key配置(调用次数、周期、增量条件等)完全保留,仅添加了范围判断

可选补充:如果需要拒绝非白名单IP

如果你不仅要限流非白名单IP,还要直接拒绝未在白名单内的请求,可以在<otherwise>块之外添加<ip-filter>,但注意顺序:

<set-backend-service id="apim-generated-policy" backend-id="name-of-my-function-app" />
<choose>
    <when condition="@(!(
        context.Request.IpAddress == "10.20.30.40" ||
        IPAddress.Parse(context.Request.IpAddress).IsInRange("10.0.0.0", "10.0.0.254") ||
        IPAddress.Parse(context.Request.IpAddress).IsInRange("10.1.0.0", "10.1.0.254") ||
        IPAddress.Parse(context.Request.IpAddress).IsInRange("10.2.0.0", "10.2.0.254")
    ))">
        <rate-limit-by-key 
            calls="60" 
            renewal-period="60" 
            counter-key="@(context.Request.IpAddress)" 
            increment-condition="@(context.Response.StatusCode == 204 ^ context.Response.StatusCode == 404)" 
            remaining-calls-variable-name="remainingCallsPerIP" />
    </when>
    <otherwise />
</choose>
<!-- 仅允许白名单IP访问,非白名单IP在限流后会被拒绝 -->
<ip-filter action="allow">
    <address-range from="10.0.0.0" to="10.0.0.254"/>
    <address-range from="10.1.0.0" to="10.1.0.254"/>
    <address-range from="10.2.0.0" to="10.2.0.254"/>
    <address>10.20.30.40</address>
</ip-filter>

内容的提问来源于stack exchange,提问作者Happy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:50:26