如何配置Azure存储Blob仅允许App Service网站访问(无需SAS令牌)
可行,以下是两种无需SAS令牌的解决方案
方案一:通过App Service代理Blob请求(推荐,兼顾安全与可控)
利用App Service已有的托管标识权限,将图片请求通过服务器端转发,同时在代理层验证用户身份与请求来源:
实现步骤
- 添加代理页面
在Razor Pages项目中创建ImageProxy.cshtml及对应的代码文件,用于处理图片请求:
// ImageProxy.cshtml.cs public class ImageProxyModel : PageModel { public async Task<IActionResult> OnGetAsync(string blobPath) { // 1. 验证用户是否通过B2C认证 if (!User.Identity.IsAuthenticated) { return Unauthorized(); } // 2. 验证请求来源Referer头 var referer = Request.Headers.Referer.ToString(); var allowedOrigins = new[] { "https://xyz.azurewebsites.net", "https://localhost:5001" }; // 替换为你的生产/本地域名 if (!allowedOrigins.Any(origin => referer.StartsWith(origin, StringComparison.OrdinalIgnoreCase))) { return Forbid(); } // 3. 通过托管标识访问Blob存储 var blobServiceClient = new BlobServiceClient( new Uri("https://xyz.blob.core.windows.net"), new DefaultAzureCredential()); var containerClient = blobServiceClient.GetBlobContainerClient("images"); var blobClient = containerClient.GetBlobClient(blobPath); if (!await blobClient.ExistsAsync()) { return NotFound(); } // 4. 返回Blob流给浏览器 var blobStream = await blobClient.OpenReadAsync(); var properties = await blobClient.GetPropertiesAsync(); return File(blobStream, properties.Value.ContentType); } }
- 修改前端图片引用
在cshtml中,将图片的src指向代理页面,传递Blob路径参数:
<img src="/ImageProxy?blobPath=image1.jpg" alt="示例图片" />
- 强化存储账户安全
在Azure存储账户的防火墙设置中,添加App Service的出站IP地址或启用服务端点(App Service),确保只有App Service能直接访问Blob存储,进一步阻断非法请求。
方案二:Azure CDN + 规则引擎验证请求来源
通过CDN缓存图片并验证Referer头,同时CDN使用托管标识访问私有Blob存储:
实现步骤
- 创建并配置Azure CDN
- 创建Azure CDN配置文件(推荐Microsoft CDN或Verizon Premium),将端点指向你的Blob存储账户(私有容器)。
- 为CDN端点启用系统托管标识,并给该标识授予Blob存储的
Blob Reader角色。
- 配置CDN规则引擎
在CDN端点的规则引擎中添加规则:
- 条件:
Referer不包含https://xyz.azurewebsites.net(及本地开发域名) - 动作:返回
403 Forbidden状态码
- 修改前端图片引用
将图片src替换为CDN端点的URL:
<img src="https://your-cdn-endpoint.azureedge.net/images/image1.jpg" alt="示例图片" />
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| App Service代理 | 无需额外服务成本,可同时验证用户身份与请求来源,安全可控 | 增加App Service的流量负载,无缓存需重复读取Blob |
| Azure CDN | 缓存图片减轻后端负载,性能更优 | 需额外支付CDN费用,用户身份验证需在App Service侧单独处理 |
内容的提问来源于stack exchange,提问作者Octopus
相关产品推荐
相关产品推荐

