【问题标题】:Constructing an Account SAS (Shared Access Signature)构建账户 SAS(共享访问签名)
【发布时间】:2016-07-18 09:55:19
【问题描述】:

我正在尝试生成帐户 SAS 令牌: MSDN DOC

当我尝试使用生成的令牌时,我得到以下信息:

AuthenticationFailed 服务器未能验证请求。确保 Authorization 标头的值正确形成,包括签名。 请求ID:89959111-0001-00c8-24d1-e0515b000000 时间:2016-07-18T08:49:00.8383767Z 签名不匹配。使用的签名字符串是 [accountName] rl b sc 2017-01-01 2015-04-05

这是我的代码:

        var signedVersion = "2015-04-05";
        var signedServices = "b";
        var signedResourceTypes = "sc";
        var signedPermission = "rl";
        var signedExpiry = "2017-01-01";

        var stringToSign =
            accountName + "\n" +
            signedPermission + "\n" +
            signedServices + "\n" +
            signedResourceTypes + "\n" +
            signedExpiry + "\n" +
            signedVersion + "\n"
            ;

        var keyBytes = Encoding.UTF8.GetBytes(accountKey);

        byte[] hash;
        using (var mac = new HMACSHA256(keyBytes))
        {
            var stringToSignBytes = Encoding.UTF8.GetBytes(stringToSign);
            hash = mac.ComputeHash(stringToSignBytes);
        }

        var str = Convert.ToBase64String(hash);
        var sig = HttpUtility.UrlEncode(str);

        var url = $"https://{accountName}.blob.core.windows.net/?comp=list&sv={signedVersion}&ss={signedServices}&srt={signedResourceTypes}&sp={signedPermission}&se={signedExpiry}&sig={sig}";

我做错了什么?

【问题讨论】:

    标签: azure azure-storage


    【解决方案1】:

    我注意到代码存在一些问题:

    首先,要将帐户密钥转换为字节数组,您需要使用Convert.FromBase64String(accountKey) 而不是Encoding.UTF8.GetBytes(accountKey);

    接下来,即使您没有使用开始时间、签名协议和签名 IP 地址,您也需要将它们包含在您的 stringToSign 中。

    完成这些操作后,代码应该可以工作了。基于这些,我在下面包含了修改后的代码。我测试了它以在我的存储帐户中列出容器并且它可以工作。

        static void AccountSas()
        {
            var signedVersion = "2015-04-05";
            var signedServices = "b";
            var signedResourceTypes = "sc";
            var signedPermission = "rl";
            var signedExpiry = "2017-01-01";
            var signedStart = "";
            var signedIP = "";
            var signedProtocol = "";
            var stringToSign =
                accountName + "\n" +
                signedPermission + "\n" +
                signedServices + "\n" +
                signedResourceTypes + "\n" +
                signedStart + "\n" +
                signedExpiry + "\n" +
                signedIP + "\n" +
                signedProtocol + "\n" +
                signedVersion + "\n"
                ;
    
            var keyBytes = Convert.FromBase64String(accountKey);
    
            byte[] hash;
            using (var mac = new HMACSHA256(keyBytes))
            {
                var stringToSignBytes = Encoding.UTF8.GetBytes(stringToSign);
                hash = mac.ComputeHash(stringToSignBytes);
            }
    
            var str = Convert.ToBase64String(hash);
            var sig = HttpUtility.UrlEncode(str);
            var url = string.Format("https://{0}.blob.core.windows.net/?comp=list&sv={1}&ss={2}&srt={3}&sp={4}&se={5}&sig={6}", accountName, signedVersion, signedServices, signedResourceTypes, signedPermission, signedExpiry, sig);
        }
    

    【讨论】:

    • 这个效果很好。因此,即使字段是可选的,stringToSign 中也需要空行...谢谢您的帮助!
    猜你喜欢
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    相关资源
    最近更新 更多