.NET使用SAS密钥读取Azure Blob时403认证失败如何解决?
问题根因分析
- SAS令牌过期
从报错的AuthenticationErrorDetail字段可以直接定位核心问题:你使用的SAS令牌有效期为2021年7月28日 22:29:14 GMT到2021年8月26日 06:29:14 GMT,而你发起请求的时间为2021年9月15日,已经完全超出SAS的有效时间范围,所以Azure直接拒绝了认证请求。 - 代码逻辑错误
你初始化的blobUri本身已经附带了完整的SAS查询参数,后续又通过UriBuilder.Query = sasToken直接覆盖了原有查询参数,如果你定义的sasToken变量值为空、格式错误或者是无效令牌,也会直接导致认证失败。
解决步骤
1. 重新生成有效SAS令牌
到Azure存储账户的对应容器/Blob下,重新生成SAS令牌:
- 有效期调整到你需要的时间范围,注意选择UTC时间避免时区差问题
- 确认权限勾选了
读取(r)权限 - 适用范围选择对应层级(容器或单个Blob)
2. 修正代码逻辑,二选一即可
方案A:直接使用完整带SAS的URI初始化BlobClient
如果你的URI已经自带了完整的SAS参数,不需要额外拼接,直接初始化即可:
namespace BlobQuickstartV12 { class Program { static async Task Main() { // 替换为你新生成的带SAS的完整Blob URI var authorizedBlobUri = new System.Uri("https://xx.blob.xx.xx.net/xxxx?你的新SAS参数"); var blobClient = new Azure.Storage.Blobs.BlobClient(authorizedBlobUri); var getBlobResponse = await blobClient.DownloadContentAsync(); Console.WriteLine("Read blob successfully", getBlobResponse.Value); } } }
方案B:纯Blob URI + 单独SAS令牌拼接
如果你要分开存储Blob地址和SAS令牌,用以下方式拼接:
namespace BlobQuickstartV12 { class Program { static async Task Main() { // 这里填不带任何查询参数的Blob原始URI var blobUri = new System.Uri("https://xx.blob.xx.xx.net/xxxx/你的Blob名称"); // 替换为你新生成的SAS令牌,注意不要带开头的? const string sasToken = "sp=ral&st=xxx&se=xxx&spr=https&sv=xxx&sr=c&sig=xxx"; var blobUriBuilder = new System.UriBuilder(blobUri) { Query = sasToken }; var authorizedBlobUri = blobUriBuilder.Uri; var blobClient = new Azure.Storage.Blobs.BlobClient(authorizedBlobUri); var getBlobResponse = await blobClient.DownloadContentAsync(); Console.WriteLine("Read blob successfully", getBlobResponse.Value); } } }
补充注意事项
- 生产环境不要硬编码SAS令牌到代码中,建议存储到机密管理组件中,避免泄露风险
- 长期访问Blob建议使用托管身份、服务主体等身份认证方式,替代固定有效期的SAS令牌
内容的提问来源于stack exchange,提问作者BRDroid
相关产品推荐
相关产品推荐

