如何通过APIM入站策略基于请求头Blob名称限制存储容器访问
Azure API Management 限制访问存储容器特定顶层目录方案
核心思路
通过APIM入站策略验证Blob的访问路径,仅允许以myfolder/开头的顶层目录请求,不符合则直接返回403 Forbidden。
方案1:验证URL路径中的Blob名称
如果你的API后端直接映射到存储Blob服务,Blob路径通常在请求URL的末尾(比如https://your-apim.azure-api.net/storage/{container}/{blob-path}),可以用以下策略提取并验证:
<policies> <inbound> <!-- 提取URL中容器之后的Blob路径部分 --> <set-variable name="blobPath" value="@(context.Request.Url.Path.Split('/').Skip(3).Aggregate((a,b) => $"{a}/{b}"))" /> <!-- 验证Blob路径是否以myfolder/开头 --> <choose> <when condition="@(!context.Variables.GetValueOrDefault<string>("blobPath").StartsWith("myfolder/", StringComparison.OrdinalIgnoreCase))"> <return-response> <set-status code="403" reason="Forbidden" /> <set-body>{"message": "仅允许访问myfolder目录下的资源"}</set-body> <set-header name="Content-Type" exists-action="override"> <value>application/json</value> </set-header> </return-response> </when> </choose> <!-- 其他入站策略 --> <base /> </inbound> <!-- 其他策略段 --> </policies>
注:Split('/').Skip(3)的数字需要根据你的APIM API URL结构调整,比如如果URL是/api/v1/storage/{container}/{blob},则用Skip(4),确保提取到的是容器之后的Blob路径。
方案2:验证请求头中的Blob名称
如果Blob名称是通过自定义请求头(比如X-Blob-Name)传递的,用以下策略验证:
<policies> <inbound> <!-- 检查是否存在目标请求头 --> <check-header name="X-Blob-Name" failed-check-httpcode="400" failed-check-error-message="缺少X-Blob-Name请求头" /> <!-- 提取头值并验证格式 --> <set-variable name="blobName" value="@(context.Request.Headers.GetValueOrDefault("X-Blob-Name", ""))" /> <choose> <when condition="@(!Regex.IsMatch(context.Variables.GetValueOrDefault<string>("blobName"), @"^myfolder/"))"> <return-response> <set-status code="403" reason="Forbidden" /> <set-body>{"message": "仅允许访问myfolder目录下的Blob"}</set-body> <set-header name="Content-Type" exists-action="override"> <value>application/json</value> </set-header> </return-response> </when> </choose> <base /> </inbound> </policies>
这里用正则^myfolder/严格匹配顶层目录,确保只有myfolder/xxx格式的Blob被允许。
关于validate-headers策略的替代用法
如果想用validate-headers直接验证头格式,也可以这么写(针对X-Blob-Name头):
<validate-headers specified-headers-only="true"> <header name="X-Blob-Name" regex="^myfolder/.*" /> </validate-headers>
不过这个策略默认会返回400错误,如果你需要返回403,还是结合choose和return-response更灵活。
备选方案:修改请求使其失败
如果不想直接返回403,也可以修改请求路径到一个无权限的位置,比如:
<choose> <when condition="@(!context.Variables.GetValueOrDefault<string>("blobPath").StartsWith("myfolder/"))"> <rewrite-uri template="/{container}/invalid-path" copy-unmatched-params="false" /> </when> </choose>
这样请求会被转发到存储的invalid-path路径,而该路径不存在或无权限,存储服务会返回404或403,不过这种方式不如直接在APIM返回403高效。
内容的提问来源于stack exchange,提问作者M.T
相关产品推荐
相关产品推荐

