Azure 构建帐户SAS(共享访问签名)

Azure 构建帐户SAS(共享访问签名),azure,azure-storage,Azure,Azure Storage,我正在尝试生成帐户SAS令牌: 当我尝试使用生成的令牌时,我得到以下结果: 身份验证失败 服务器无法对请求进行身份验证。确保包括签名在内的授权标头的值格式正确。 请求ID:89959111-0001-00c8-24d1-e0515b000000 时间:2016-07-18T08:49:00.8383767Z 签名不匹配。要签名的字符串为[accountName] rl B sc 2017-01-01 2015-04-05 这是我的代码: var signedVersion

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

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

身份验证失败 服务器无法对请求进行身份验证。确保包括签名在内的授权标头的值格式正确。 请求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}";

我做错了什么?

我注意到代码有一些问题:

首先,要将帐户密钥转换为字节数组,需要使用
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);
    }

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

首先,要将帐户密钥转换为字节数组,需要使用
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中也需要空行。。。谢谢你的帮助!这个很好用。所以,即使字段是可选的,stringToSign中也需要空行。。。谢谢你的帮助!