【问题标题】:How to generate the Azure Table Service SAS token from c# code?如何从 c# 代码生成 Azure 表服务 SAS 令牌?
【发布时间】:2017-08-16 13:21:18
【问题描述】:

我想从 C# 代码为 Azure 表服务生成 SAS 令牌。我从门户网站生成了一个,看起来像

?sv=2016-05-31&ss=t&srt=sco&sp=rwdlacu&se=2017-03-23T20:05:14Z&st=2017-03-23T12:05:14Z&sip={MY_IP}&spr=https&sig=fL9GNAZqybSlQKWvaspwr%2FrFFtWO%2F5jVgFu1Ayu94Ic%3D

如何从 c# 代码生成这种令牌?如果有任何教程,请将我重定向到它。 我尝试了下面的方法,但是生成的令牌无效。

更新代码

我仍然收到错误403 Forbidden。我计算签名的代码是否正确?

var StringToSign = "{Storage_account_name}" + "\n" +
                            "rwdlacu" + "\n" +
                            "t" + "\n" +
                            "sco" + "\n" +
                            "2017-03-24T12:05:14Z" + "\n" +
                            "2017-03-24T20:05:14Z" + "\n" +
                            "{IP}" + "\n" +
                            "https" + "\n" +
                            "2016-05-31" + "\n";
string encodedString = HttpUtility.UrlEncode(StringToSign);
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String("accountkey"));
var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(encodedString)));

【问题讨论】:

    标签: c# azure azure-table-storage


    【解决方案1】:

    您遇到问题的原因是您正在根据计算 Authorization 标头的逻辑计算 SAS 的签名。 StringToSign 在两种情况下都不同。

    对于 SAS,这应该是(对于 Service SAS):

    StringToSign = signedpermissions + "\n" +  
                   signedstart + "\n" +  
                   signedexpiry + "\n" +  
                   canonicalizedresource + "\n" +  
                   signedidentifier + "\n" +  
                   signedIP + "\n" +  
                   signedProtocol + "\n" +  
                   signedversion + "\n" +  
                   startingPartitionKey + "\n"  
                   startingRowKey + "\n"  
                   endingPartitionKey + "\n"  
                   endingRowKey  
    

    如果你想使用Account SAS(这是 Portal 所做的),应该是:

    StringToSign = accountname + "\n" +  
        signedpermissions + "\n" +  
        signedservice + "\n" +  
        signedresourcetype + "\n" +  
        signedstart + "\n" +  
        signedexpiry + "\n" +  
        signedIP + "\n" +  
        signedProtocol + "\n" +  
        signedversion + "\n"  
    

    因此,根据您的参数,Account SAS 的 StringToSign 将是:

    StringToSign = {youraccountname} + "\n" +  
        "rwdlacu" + "\n" +  
        "t" + "\n" +  
        "sco" + "\n" +  
        "2017-03-23T12:05:14Z" + "\n" +  
        "2017-03-23T20:05:14Z" + "\n" +  
        {yourip} + "\n" +  
        "https" + "\n" +  
        "2016-05-31 + "\n"  
    

    signature 的计算是正确的。

    您可能会发现这些链接有助于了解有关计算 SAS 的更多信息:Account SASService SAS

    更新

    hmac 计算也存在问题。它应该使用您的帐户密钥,并且应该使用Convert.FromBase64String

    HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(accountKey));
    

    另外,你不应该 URLEncode StringToSign。那里的元素应该被 URL 解码。

    最后,SAS 令牌应该看起来像您从门户返回的内容。

    代码示例

        static void AccountSasSample()
        {
            var accountName = "your-account-name";
            var accountKey = "your-account-key";
            var start = DateTime.UtcNow.AddHours(-1).ToString("yyyy-MM-ddTHH:mm:ssZ");
            var end = DateTime.UtcNow.AddHours(1).ToString("yyyy-MM-ddTHH:mm:ssZ");
            var permission = "rwdlacu";
            var serviceType = "t";
            var resourceTypes = "sco";
            var ipAddress = "your-ip-address";
            var protocol = "https";
            var serviceVersion = "2016-05-31";
            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, ipAddress, protocol, serviceVersion);
            Console.WriteLine(stringToSign);
            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}&sip={6}&spr={7}&sig={8}", serviceVersion,
                serviceType, resourceTypes, permission, end, start, ipAddress, protocol, HttpUtility.UrlEncode(signature));
            Console.WriteLine(sasToken);
            var urlToListTables = string.Format("https://{0}.table.core.windows.net/Tables{1}", accountName, sasToken);
            //Copy this urlToListTables & paste it in browser's address bar. You should be able to see the list of tables in your storage account.
        }
    

    【讨论】:

    • 我仍然收到错误 403 Forbidden。我计算签名的代码是否正确? 我已更新问题中的代码
    • 签名计算也有问题。让我编辑我的答案。
    • 是的,我的字符串格式正确,但即使在接受了您建议的 HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String("account key"); 更改之后,我仍然收到 403 Forbidden 错误。
    • 您上面的代码仍然是对 StringToSign 进行 URL 编码。你不需要这样做。
    • 你能提供样品吗?我对编码什么以及将什么转换为 hmac 感到困惑?
    【解决方案2】:
    //account name               
    var storageAccountName = ConfigProvider.AccountName;
    // your storage account access key here
    var accessKey = ConfigProvider.BlobKey;
    
    // connect to our storage account and create a blob client
    var connectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
        storageAccountName,
        accessKey);
    var storageAccount = CloudStorageAccount.Parse(connectionString);
    var blobClient = storageAccount.CreateCloudBlobClient();
    
    SharedAccessAccountPolicy policy = new SharedAccessAccountPolicy()
    {
        Permissions = SharedAccessAccountPermissions.Write | SharedAccessAccountPermissions.Create,
        Services = SharedAccessAccountServices.Blob,
        ResourceTypes = SharedAccessAccountResourceTypes.Container | SharedAccessAccountResourceTypes.Object,
        SharedAccessExpiryTime = DateTime.UtcNow.AddMonths(1),
        Protocols = SharedAccessProtocol.HttpsOnly,
    };
    
    string sasToken = storageAccount.GetSharedAccessSignature(policy);
    

    【讨论】:

      【解决方案3】:

      为什么不使用 Azure 存储客户端库来生成 SAS?可以参考:https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1

      【讨论】:

        猜你喜欢
        • 2018-03-28
        • 2018-08-14
        • 2019-01-14
        • 1970-01-01
        • 2019-06-05
        • 2020-05-29
        • 2020-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多