c# - 从 API 身份验证返回的 Azure Blob SAS Url 失败 .net 核心
问题描述
我正在尝试将 SAS url 返回到我的前端,以便我可以将用户重定向到该链接,以便他们可以下载文件。
这是我创建 SAS url 的代码
private SasQueryParameters GenerateSaSCredentials(string containerName, string blobName) {
// Defines the resource being accessed and for how long the access is allowed.
BlobSasBuilder blobSasBuilder = new() {
StartsOn = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(10)),
ExpiresOn = DateTime.UtcNow.Add(TimeSpan.FromMinutes(120)) + TimeSpan.FromSeconds(1),
Resource = "b",
BlobName = blobName,
BlobContainerName = containerName
};
// Defines the type of permission.
blobSasBuilder.SetPermissions(BlobSasPermissions.Read);
// Builds an instance of StorageSharedKeyCredential
StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _key);
// Builds the Sas URI.
return blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential);
}
public Uri CreateBlobUri(string blobName, string containerName) {
SasQueryParameters parameters = GenerateSaSCredentials(containerName, blobName);
return new UriBuilder {
Scheme = "https",
Host = $"{_accountName}.blob.core.windows.net",
Path = $"files/{containerName}/{blobName}",
Query = WebUtility.UrlDecode(parameters.ToString())
}.Uri;
}
您可能会注意到 parameters.ToString() 上的 url 解码是因为我在 stackoverflow 上看到了类似的问题,他们谈到了双重编码。
但是,当我将此 url 返回到浏览器并重定向时,我收到以下错误。
这就是我返回 URL 的方式
return Ok(_blobUtils.CreateBlobUri(fileName, containerName).ToString());
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header
is formed correctly including the signature. RequestId:01696cca-d01e-0023-2ea4-74f5df000000
Time:2021-07-09T09:23:33.0250817Z</Message>
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>
如果我从中删除 WebUtility.UrlDecode parameters.ToString()
,我会收到此错误
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header
is formed correctly including the signature. RequestId:016a1821-d01e-0023-3da4-74f5df000000
Time:2021-07-09T09:24:38.4051042Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2021-07-
09T09:14:38Z 2021-07-09T11:24:39Z /blob/${_acountName}/files/bqXbY54sRRsipOUB1PF6/fyI67FYOqDS80y1vNWRL/PRE_OP_CT/0/TK1.left.TST.PTN1.PRE
_OP_CT.zip 2020-04-08 b </AuthenticationErrorDetail>
</Error>
我试图访问的 Blob 的结构是:
谁能明白为什么这会失败?
解决方案
files
请从Path
这里摆脱:
return new UriBuilder {
Scheme = "https",
Host = $"{_accountName}.blob.core.windows.net",
Path = $"files/{containerName}/{blobName}",
Query = WebUtility.UrlDecode(parameters.ToString())
}.Uri;
它应该是这样的:
return new UriBuilder {
Scheme = "https",
Host = $"{_accountName}.blob.core.windows.net",
Path = $"{containerName}/{blobName}",
Query = WebUtility.UrlDecode(parameters.ToString())
}.Uri;
更新
根据屏幕截图和错误消息,您的容器files
名称为 ,blob 名称为bqXbY54sRRsipOUB1PF6/fyI67FYOqDS80y1vNWRL/PRE_OP_CT/0/TK1.left.TST.PTN1.PRE
. 请在您的代码中使用它们,您应该不会收到错误消息。您仍然需要files
从上面的路径中删除,因为它已经包含在您的containerName
.
您的代码失败的原因是因为您正在为 blob 容器内的 blob 计算 SAS 令牌(blob 路径变为container-name/blob-name
)。但是,在您的请求中,您在files
请求 URL 之前,您的 blob 路径变为files/container-name/blob-name
. 由于 SAS 令牌是针对不同路径获取的,但用于其他路径,因此您会收到错误消息。