基于请求头通过APIM阻止公网IP访问的实现咨询
解决方案
由于APIM部署在Application Gateway后方,默认的ip-filter策略只能识别网关的IP,无法直接过滤原始客户端IP。你需要通过解析请求头中的原始IP(若实际原始IP存放在x-original-host头中,可替换下方策略里的x-forwarded-for),结合APIM的策略表达式实现私有IP段的访问控制。
以下是符合需求的完整APIM策略代码,通过C#表达式判断IP是否属于指定私有段,不符合则直接返回403拒绝访问:
<policies> <inbound> <base /> <!-- 获取头中的原始客户端IP,处理多代理场景下的逗号分隔IP列表,取第一个 --> <set-variable name="clientIp" value="@(context.Request.Headers.GetValueOrDefault("x-forwarded-for", "").Split(',')[0].Trim())" /> <!-- 判断IP是否属于私有IP段,不符合则拒绝 --> <choose> <when condition="@( // 匹配A类私有段:10.0.0.0 - 10.255.255.255 Regex.IsMatch((string)context.Variables["clientIp"], @"^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$") || // 匹配B类私有段:172.16.0.0 - 172.31.255.255 Regex.IsMatch((string)context.Variables["clientIp"], @"^172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}$") || // 匹配C类私有段:192.168.0.0 - 192.168.255.255 Regex.IsMatch((string)context.Variables["clientIp"], @"^192\.168\.\d{1,3}\.\d{1,3}$") )"> <!-- IP符合私有段规则,允许请求继续流转 --> </when> <otherwise> <!-- IP不符合规则,返回403拒绝访问 --> <return-response> <set-status code="403" reason="Forbidden" /> <set-body>{"message": "仅允许私有IP段访问"}</set-body> <set-header name="Content-Type" exists-action="override"> <value>application/json</value> </set-header> </return-response> </otherwise> </choose> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
关键说明:
- 用
set-variable提取头中的第一个IP:x-forwarded-for可能包含多个代理IP(逗号分隔),第一个为原始客户端IP - 正则表达式精准匹配三个私有IP段的格式范围,避免误判
- 不符合规则的请求直接通过
return-response终止流程,返回403状态码和提示信息
内容的提问来源于stack exchange,提问作者dcvl
相关产品推荐
相关产品推荐

