ASP.NET MVC中Azure Blob SAS签名格式错误求助
问题:Azure Blob SAS签名格式错误导致AuthenticationFailed
我在ASP.NET MVC中使用以下VB.NET代码生成Azure Blob的SAS并拼接至Blob URL,但无法正常工作:
Dim sasUrl As String = imageUrl 'https://**blob.core.windows.net/mycontainer/site/GroupImages/Tabs/image.png Dim blobSasBuilder As Azure.Storage.Sas.BlobSasBuilder = New Azure.Storage.Sas.BlobSasBuilder() With { .BlobContainerName = _azContainerName, .StartsOn = DateTime.UtcNow.AddMinutes(-30), .ExpiresOn = DateTime.UtcNow.AddHours(1) } blobSasBuilder.SetPermissions(Sas.BlobSasPermissions.Read) Dim sasToken = blobSasBuilder.ToSasQueryParameters(New StorageSharedKeyCredential(_azAccountName, _azAccountKey)).ToString() sasUrl += "?" + sasToken Return sasUrl
执行后收到如下错误:
AuthenticationFailed
服务器未能验证请求。请确保Authorization标头的值(包括签名)格式正确。
RequestId: 83ab7db1-501e-0043-6a84-f2ac67000000
Time: 2023-09-29T03:27:02.8112176Z
Signature fields not well formed.
编辑1:
修改代码指定Blob名称为规范格式后问题依旧,调整后的代码如下:
Dim blobClient As BlobClient = _blobServiceClient.GetBlobContainerClient(_azCompanyContainerName).GetBlobClient("site/GroupImages/Tabs/pizza.png") Dim blobSasBuilder As BlobSasBuilder = New BlobSasBuilder() With { .BlobContainerName = _azCompanyContainerName, .BlobName = "site/GroupImages/Tabs/pizza.png", .Resource = "b", .ExpiresOn = DateTimeOffset.UtcNow.AddHours(1), .Protocol = SasProtocol.Https }
编辑2:
发现当SAS Token中包含“+”符号时会触发错误,例如以下无效Token:
sig=+Z9OWuihzHYWmdXToy53OS7y+PN2qtBPwhzgIYSsLTQ=
解决方案
问题根源在于SAS Token中的+符号在URL中会被自动解析为空格,导致签名格式失效。需要对生成的SAS Token进行URL编码,确保特殊字符被正确转义。
修改后的代码示例
使用HttpUtility.UrlEncode(需引用System.Web命名空间)处理SAS Token:
' 生成SAS Token Dim sasToken = blobSasBuilder.ToSasQueryParameters(New StorageSharedKeyCredential(_azAccountName, _azAccountKey)).ToString() ' 对SAS Token进行URL编码,转义特殊字符 Dim encodedSasToken = HttpUtility.UrlEncode(sasToken) ' 拼接最终URL sasUrl += "?" + encodedSasToken Return sasUrl
若不想引用System.Web,可使用Uri.EscapeDataString替代:
Dim encodedSasToken = Uri.EscapeDataString(sasToken) sasUrl += "?" + encodedSasToken
额外注意事项
- 生成Blob级SAS时,必须明确指定
.BlobName和.Resource = "b"(b代表Blob资源类型) - 时间参数建议使用
DateTimeOffset而非DateTime,避免时区偏差导致的签名验证失败
内容的提问来源于stack exchange,提问作者Ris
相关产品推荐
相关产品推荐

