2012-01-02 57 views
2

我試圖通過Web服務爲我的blob提供「只讀」訪問權限。 Web Service具有一種方法,它接收Blob和Container信息,然後返回一個帶有共享訪問簽名的URL,以便用戶訪問該Blob。由於這些圖像(斑點)在電話上緩存,我想保持簽名有效期長達1天。SharedAccessSignature Azure

我使用下面的代碼:

 var blobClient = GetBlobClient(); 
     var container = blobClient.GetContainerReference(containerName); 
     if (container != null) 
     { 
      container.CreateIfNotExist(); 
     } 

     var policy = new SharedAccessPolicy() 
     { 
      SharedAccessStartTime = DateTime.Now, 
      Permissions = SharedAccessPermissions.Read, 
      SharedAccessExpiryTime = DateTime.Now.AddDays(days) 
     }; 

     if (permissions.Contains("w")) 
     { 
      policy.Permissions = policy.Permissions | SharedAccessPermissions.Write; 
      policy.SharedAccessExpiryTime = DateTime.Now.AddMinutes(10); 
     } 

     //The shared access policy provides read/write access to the container for 10 hours. 
     BlobContainerPermissions containerPerms = new BlobContainerPermissions(); 
     // The public access setting explicitly specifies that the container is private, 
     // so that it can't be accessed anonymously. 
     containerPerms.PublicAccess = BlobContainerPublicAccessType.Off; 
     containerPerms.SharedAccessPolicies.Clear(); 
     containerPerms.SharedAccessPolicies.Add("mypolicy", policy); 
     // Set the permission policy on the container. 
     container.SetPermissions(containerPerms); 

     var blob = container.GetBlobReference(blobName); 
     // Get the shared access signature to share with users. 
     var blobPolicy = new SharedAccessPolicy(); 
     blobPolicy.SharedAccessExpiryTime = DateTime.Now.AddDays(days); 
     blobPolicy.Permissions = SharedAccessPermissions.Read; 
     string sas = blob.GetSharedAccessSignature(blobPolicy, "mypolicy"); 

     return sas; 

每次我嘗試使用此代碼,我得到以下錯誤: 簽名不匹配。串籤使用爲r 2012-01-03T08:38:52Z /myContainer/12100/12409/29cae1b6-2955-4a33-ab27-ff99f0bb6470_m.jpg mypolicy

任何人都可以請指導我這個?

回答

0

也許這是因爲共享訪問簽名不能超過一個小時。爲了有一個多小時的SAS,你需要使用容器級別政策(你可以撤銷)從article

One way that you can manage a Shared Access Signature is to control its lifetime by ensuring that it expires within an hour. If you want to continue to grant a client access to the blob after that time period, you must issue a new signature. This is the behavior of a Shared Access Signature that is not associated with a container-level access policy. A Shared Access Signature not bound to a container-level access policy cannot be revoked. If a start time is specified, the expiration time must be 60 or fewer minutes from the start time, or the signature is invalid and cannot be used. If no start time is specified, the signature is valid only during the 60 minute period before the expiration time. This policy is intended to minimize risk to a storage account in the event that the signature is leaked.

Another way to manage a Shared Access Signature is to associate the signature with a container-level access policy. The container-level access policy is represented by the signedidentifier field on the URL. A container-level access policy provides an additional measure of control over one or more Shared Access Signatures, including the ability to revoke the signature if needed.

1

它看起來像你對「mypolicy」完全設置SAS政策 摘錄集裝箱。一旦你這樣做了,他們就不會打開後續修改查詢字符串參數。這是一個'填空'系統。您可以在查詢字符串上指定的唯一部分是未在容器策略中指定並保存的部分(即填充空白)。所以,在這種情況下,你有

blobPolicy.SharedAccessExpiryTime = DateTime.Now.AddDays(days); 
blobPolicy.Permissions = SharedAccessPermissions.Read; 

但是,這兩個選項已經保存的政策,所以你不能再指定它們(他們增加導致查詢字符串)。如果你想指定這些,你不應該讓它們保存在初始SetPermission()上。

你可以通過註釋掉這兩行來證明這一點,你的簽名應該是有效的。

3

我懷疑問題在於URL的「簽名」組件(sig參數)。

的URL來訪問你的BLOB需要在這種形式,如果你使用60分鐘的URL,而不在其上的政策:

http://[storage account name].blob.core.windows.net/[top level container name]/[filename of BLOB]?sr=b&st=2012-01-19T12:21:40Z&se=2012-01-19T13:21:40Z&sp=r&sig=[Base-64 encoded signature] 

或在這種形式,如果你使用的策略:

http://[storage account name].blob.core.windows.net/[top level container name]/[filename of BLOB]?sr=b&st=2012-01-19T12:21:40Z&se=2012-01-19T13:21:40Z&si=[name of security policy]&sig=[Base-64 encoded signature] 

關於簽名(在URL參數SIG的:) 微軟僞表明他們希望我們如何生成簽名:

Signature=Base64(HMAC-SHA256(UTF8(StringToSign))) 

你如何讓字符串標記?見http://msdn.microsoft.com/en-us/library/windowsazure/ee395415.aspx

StringToSign = signedpermissions + "\n" + signedstart + "\n" + signedexpiry + "\n" + canonicalizedresource + "\n" + signedidentifier

的換行符是至關重要的 - 這是相當於十六進制字符是0xA。標準Java「\ n」換行符很好。不要忽略它們或不起作用。

可以將signedpermissions設置爲空 - 只要您在簽名許可後仍然包含換行符(如果爲空)。

如果簽名權限已填充,那麼signedidentifier可以爲空。你不需要在它之後放置一個換行字符。

在運行HMAC SHA256散列之前,必須確保將字符串轉換爲UTF-8(Unicode 8)。

http://msdn.microsoft.com/en-us/library/windowsazure/hh508996.aspx

The string-to-sign is a unique string constructed from the fields that must be verified in order to authenticate the request. The signature is an HMAC computed over the string-to-sign and key by using the SHA256 algorithm, and then encoded by using Base64 encoding.