2017-03-23 41 views
0

我想從C#代碼中爲Azure表服務生成SAS令牌。我生成了一個從門戶看起來像如何從c#代碼生成Azure Table Service 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禁止。我的代碼是否正確計算簽名?

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))); 

回答

1

你遇到這個問題的原因是因爲你正在計算簽名的SAS基於邏輯計算Authorization頭。在兩種情況下,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(這是門戶網站做什麼),它應該是:

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

因此,基於您的參數,StringToSign帳戶SAS將是:

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" 

The computatio n代表signature是正確的。

您可能會發現這些鏈接有助於瞭解有關計算SAS的更多信息:Account SASService SAS

UPDATE

有與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. 
    } 
+0

我仍然得到禁止錯誤** ** 403。我的代碼是否正確計算簽名? **我更新了問題**中的代碼。 – Sameer

+0

簽名計算也存在問題。讓我編輯我的答案。 –

+0

是的,我正確地格式化字符串,但是即使在適應您建議的'HMACSHA256 hmac = new HMACSHA256(Convert。FromBase64String(「account key」);'我得到** 403 Forbidden **錯誤。 – Sameer

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);