Azure存储SAS身份验证失败

时间:2017-05-30 04:13:26

标签: c# azure asp.net-core azure-storage azure-storage-blobs

我有一个私有的天蓝色存储容器,我正在尝试使用azure存储SAS,以便我可以上传和下载文件。 我能够生成签名,但它总是抛出身份验证失败错误

  

      AuthenticationFailed       服务器无法验证请求。确保正确形成Authorization标头的值,包括   签名。请求ID:a9dce486-0001-0021-23f7-d8f6dc000000   时间:2017-05-30T03:45:56.6617677Z       签名不匹配。使用的字符串是r 2017-05-30T03:40:48Z 2017-05-30T03:55:48Z   /斑点/ {我的账户} / {myContainer中} /11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg

     

2016年5月31日

     

这是我生成的签名供我使用,并返回完整的URI以访问该文件。

var accountAndKey = new StorageCredentials("******", "*********************");
var storageAccount = new CloudStorageAccount(accountAndKey, true);

var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5);
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;


CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("*****");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg");

var sasBlobToken = blockBlob.GetSharedAccessSignature(sasConstraints);

var sas = blockBlob.Uri + sasBlobToken;

return sas;

这是它生成的签名

  

SV = 2016年5月31日&安培; SR = B和= SIG%9fUwDWfdtUifv9iZXJKgILEM7Yx1uP3Ku0vrspjWyz8 3D&安培; ST = 2017-05-30T03%3A40%3A43Z&安培; SE = 2017-05-30T03%3A55%3A43Z&安培; SP = R < / p>

我使用Azure门户生成签名,它工作正常。我追加它,并能像往常一样下载文件。 这是它生成的签名

  

SV = 2016年5月31日&安培; SS = B和SRT = SCO&安培; SP =的R&amp; SE = 2017-05-30T03:57:25Z&安培; ST = 2017-05-30T03:52:25Z&安培; SPR = HTTPS&安培; SIG = JOnhkge0QWNdv8sXJjb5GazTo9c34KH1IvZBvcNgjHo%3D

我高度怀疑它是时间戳的问题。因为我可以看到我从代码中生成的内容与从门户生成的内容之间的时间戳有所不同。

非常感谢任何想法。感谢。

修改 我更新了代码,添加了一天直到到期并删除了开始时间,这是现在的签名

  

SV = 2016年5月31日&安培; SR = B和= SIG%73立方米2BJ%2BUsFk537vd8a7F%2BdpdON1Pg2RZ1IRynMH4zGA%3D&安培; SE = 2017-05-31T06%3A12%3A07Z&安培; SP = R

但它仍然不允许我下载该文件。相同的错误消息。

  

签名不匹配。使用的字符串是r 2017-05-31T06:12:07Z / blob / {MyAcc} / {My Container} /11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg 2016-05-31

1 个答案:

答案 0 :(得分:0)

我也无法使用代码重现该问题。这是一种可以在不使用GetSharedAccessSignature方法的情况下生成SAS的方法。请尝试一下,检查一下它是否适合您。

private static string GetSharedAccessSignature(
       string accountName,
       string accountkey,
       string blobContainer,
       string blobName,
       DateTimeOffset sharedAccessStartTime,
       DateTimeOffset sharedAccessExpiryTime)
{
    var canonicalNameFormat = $"/blob/{accountName}/{blobContainer}/{blobName}";
    var st = sharedAccessStartTime.UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
    var se = sharedAccessExpiryTime.UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
    var sasVersion = "2016-05-31";

    string stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}\n{12}", new object[]
    {
        "r",
        st,
        se,
        canonicalNameFormat,
        string.Empty,
        string.Empty,
        string.Empty,
        sasVersion,
        string.Empty,
        string.Empty,
        string.Empty,
        string.Empty,
        string.Empty
    });

    var sas = GetHash(stringToSign, accountkey);

    var credentials =
        $"?sv={sasVersion}&sr=b&sig={UrlEncoder.Default.Encode(sas)}&st={UrlEncoder.Default.Encode(st)}&se={UrlEncoder.Default.Encode(se)}&sp=r";

    string blobUri = $"https://{accountName}.blob.core.windows.net/{blobContainer}/{blobName}";
    return blobUri + credentials;
}

private static string GetHash(string stringToSign, string key)
{
    byte[] keyValue = Convert.FromBase64String(key);

    using (HMACSHA256 hmac = new HMACSHA256(keyValue))
    {
        return Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
    }
}