c# - 如何从 C# 代码生成 Azure 表服务 SAS token ?

标签 c# azure azure-table-storage

我想从 C# 代码生成 Azure 表服务的 SAS token 。我从门户生成了一个看起来像

?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# 代码生成此类 token ?如果有任何教程,请将我重定向到它。 我尝试了下面的方法,但生成的 token 无效。

更新代码

我仍然收到错误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)));

最佳答案

您遇到此问题的原因是您正在根据计算 Authorization header 的逻辑来计算 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"  

签名的计算是正确的。

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

更新

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

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

此外,您不应该对 StringToSign 进行 URLEncode。那里的元素应该经过 URL 解码。

最后,SAS token 应该与您从门户返回的 token 类似。

代码示例

    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.
    }

关于c# - 如何从 C# 代码生成 Azure 表服务 SAS token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42985347/

相关文章:

azure - Terraform:将整个资源组移动到新的 Azure 订阅

c# - 如何将 Table.ExecuteQuerySegmentedAsync() 与 Azure 表存储结合使用

c# - 查找具有用户指定大小的数组的平均值 C#

c# - 如何调试 EF? (分析 SQL 查询)

azure - Azure RM PowerShell 模块中的 Enable-AzStorageStaticWebsite 命令

Azure 资源管理器部署超时

azure - 更新 Azure 表存储记录时如何避免竞争条件

c# - ServiceContext.SaveChangesWithRetries 与 SaveChangesOptions.Batch 异常

c# - IEnumerator IEnumerable vb 到 C#

c# - WebSecurity.CreateUserAndAccount 属性值