0

我正在尝试将下载器附加到要从 blob 存储下载文件的服务总线。但是我在手动生成 SAS 令牌时遇到了一些问题,请参阅下面的错误消息。

我收到错误<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>

    private static string createToken(string resourceUri, string keyName, string key)
    {
        var now = DateTime.UtcNow;

        TimeSpan sinceEpoch = now - new DateTime(1970, 1, 1);

        var time = 60 * 2;

        var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + time);
        var expiryDateString = now.AddSeconds(time).ToUniversalTime().ToString("u");

        string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;

        HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));

        var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        var sasToken = String.Format(
            CultureInfo.InvariantCulture,
            "{0}?sp={1}&st={2}&se={3}&spr={4}&sv={5}&sr={6}&sig={7}",
            resourceUri,
            "r",
            DateTime.UtcNow.ToUniversalTime().ToString("u"),
            expiryDateString,
            "https",
            "2019-02-02",
            "b",                
            HttpUtility.UrlEncode(signature));

        return sasToken;
    }

stringToSign吗?还是signature作为一个整体?我很不习惯,也许我需要在所有字段上使用 HttpUtility.UrlEncoder ?

4

1 回答 1

0

请尝试下面的代码,它会为我生成一个有效的 sas 令牌:

static void Main(string[] args)
{
    string resourceUri = "https://xx.blob.core.windows.net/test1/1.txt";
    string account_name= "storage account name";
    string key = "storage account key";

    string s1 = createToken(resourceUri,account_name,key);

    Console.WriteLine(s1);

    Console.ReadLine();
}

private static string createToken(string resourceUri, string account_name, string key)
{
    var accountName = account_name;
    var accountKey = key;
    var start = DateTime.UtcNow.AddHours(-2).ToString("yyyy-MM-ddTHH:mm:ssZ");
    var end = DateTime.UtcNow.AddHours(2).ToString("yyyy-MM-ddTHH:mm:ssZ");
    var permission = "rwdlac";
    var serviceType = "b";
    var resourceTypes = "sco";
    var protocol = "https";
    var serviceVersion = "2019-02-02";

    //here is the difference from your code.
    var stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n",accountName, permission,serviceType,resourceTypes,start,end,"",protocol,serviceVersion);

    HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(accountKey));
    string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
    var sasToken = string.Format("?sv={0}&ss={1}&srt={2}&sp={3}&se={4}&st={5}&spr={6}&sig={7}", serviceVersion,
        serviceType, resourceTypes, permission, end, start, protocol, HttpUtility.UrlEncode(signature));

    var urlToListTables = resourceUri + sasToken;

    return urlToListTables;
}

如果您还有任何问题,请告诉我。

于 2020-02-14T06:56:37.243 回答