在前面一篇文章中,我們演示了在Windows store應用中安全的使用Azure Blob存儲的步驟。 Windows Phone上的步驟與此類似,只是在用戶端代碼以及設置方面有一些區別。 但是為了方便讀者閱讀,我這裡將就Windows Phone應用中如何安全的使用Azure Blob存儲單獨寫一遍。 這樣對於Windows Phone開發者來說,只需要看這篇文章就夠了。
我們已經在這篇文章中演示了在Windows Phone應用中使用Azure Blob存儲的基本步驟,但是,對於一個商業應用來說,保證資料的安全性是很重要的一環。 上次文章的代碼中,對Blob的存取權限是通過PublicAccess來控制的,理論上如果PublicAccess設置為OFF,那麼協力廠商就應該無法訪問該Blob。 但是這裡有一個明顯的安全隱患:我們的代碼中明文存儲了Access Key字串,而通過一些反編譯工具協力廠商能夠很容易的獲得這個字串。 如果這個Access Key被暴露的話,那麼Blob中的內容就毫無秘密可言了。 為此,我們需要找到一個可靠的辦法來保證驗證資訊的安全。
為了解決這個問題,我們需要做到以下兩條:
1.保證使用者在未經授權的情況下無法獲得驗證資訊。
2.使用者通過授權後獲得的驗證資訊不能被重複使用。
對於第一條,我們可以自己建立一個伺服器,與該伺服器的連接需要先進行身份驗證,然後從伺服器上獲得用於連接Windows Azure 存儲服務的驗證資訊。 不過我們既然已經使用了Windows Azure,那麼完全可以使用Windows Azure 雲服務來為我們做同樣的事情。
對於第二條,Windows Azure 存儲服務提供了共用訪問簽名(Shared Access Signature)來保證驗證資訊的時效性。 共用訪問簽名是一個在特定時間間隔內授予容器、Blob以及其他存儲物件受限存取權限的 URI。 也就是說,共用訪問簽名是一個URI, 用戶端通過這個URI能夠在規定時間內訪問容器和Blob, 而超過了時間段的話這個URI就無效了,需要重新獲取。
結合這兩種方式,那麼我們就能夠實現對驗證資訊的保護了。 我們將生成共用訪問簽名的代碼放在Windows Azure雲服務上,用戶端通過訪問雲服務介面獲得共用訪問簽名來訪問Windows Azure存儲服務商的Blob。
那麼讓我們來看看如果要安全的實現與前一篇文章相同的功能所需要完成的步驟。
一. 創建雲服務並實現服務介面:
1. 從以下連結下載並安裝Azure Cloud Service SDK For .NET:
HTTP://www.windowsazure.com/en-us/downloads/?sdk=net
針對不同的Visual Studio版本,您需要安裝相應的SDK,這樣在您的Visual Studio的專案範本中會出現Azure Cloud Service的範本。
2. 通過Azure Cloud Service範本創建一個Cloud服務,在專案嚮導中加入WCF Service Web Role:
完成後項目嚮導會自動建立兩個專案,一個是Cloud Service專案WindowsAzure1,另一個是提供WCF Service的Web Role專案WCFServiceWebRole1。 WCFServiceWebRole1中會生成一個名為IService1的介面及實現該介面Service1類。
3. 修改WCFServiceWebRole1專案中的IService1介面添加用於獲取共用訪問簽名的介面函數:
public interface IService1
{
[OperationContract]
string[] GetUploadSAS(string ContainerName, string BlobName);
[OperationContract]
string[] GetDownloadSAS(string ContainerName, string BlobName);
}
這兩個介面函數一個用來獲得用於上傳的共用訪問簽名,一個用來獲得用於下載的共用訪問簽名,它們都接收兩個參數:容器名稱和Blob名稱,返回一個含有兩個字串的字串陣列,第一個字串用來存放用於訪問Blob的URI, 第二個字串用來存放共用訪問簽名。
4. 在WCFServiceWebRole1專案的Service1類中實現GetUploadSAS函數用來返回用於上傳的共用訪問簽名,與上一篇演示的圖片上傳代碼類似,我們首先使用帳號名與訪問金鑰建立Blob用戶端物件實例, 然後根據容器名得到容器的物件實例,如果容器不存在的話則建立容器並且關閉對匿名使用者的存取權限。 然後,我們通過Blob名獲得Blob塊物件實例,通過該實例調用GetSharedAccessSignature獲得一個具有5分鐘讀寫存取權限的共用訪問簽名。
public string[] GetUploadSAS(string ContainerName, string BlobName)
{
string[] blobInfo = new string[2];
if (string. IsNullOrEmpty(ContainerName) || string. IsNullOrEmpty(BlobName))
{
throw new ArgumentNullException();
}
var credentials = new StorageCredentials(accountName, accessKey);
var account = new CloudStorageAccount(credentials, true);
var blobClient = account. CreateCloudBlobClient();
var container = blobClient.GetContainerReference(ContainerName);
container. CreateIfNotExists();
BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
containerPermissions.PublicAccess = BlobContainerPublicAccessType.Off;
container. SetPermissions(containerPermissions);
var blob = container. GetBlockBlobReference(BlobName);
blobInfo[0] = blob. Uri.AbsoluteUri;
blobInfo[1] = blob. GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5),
Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read
});
return blobInfo;
}
5. 在WCFServiceWebRole1專案的Service1類中實現GetDownloadSAS函數用來返回用於下載圖片的共用訪問簽名,代碼與步驟4類似,首先使用帳號名與訪問金鑰建立Blob用戶端物件實例, 然後根據容器名得到容器的物件實例,接下來就可以通過Blob名獲得Blob塊物件實例,調用該實例的GetSharedAccessSignature函數來獲得一個具有5分鐘唯讀存取權限的共用訪問簽名:
public string[] GetDownloadSAS(string ContainerName, string BlobName)
{
string[] blobInfo = new string[2];
if (string. IsNullOrEmpty(ContainerName) || string. IsNullOrEmpty(BlobName))
{
throw new ArgumentNullException();
}
var credentials = new StorageCredentials(accountName, accessKey);
var account = new CloudStorageAccount(credentials, true);
var blobClient = account. CreateCloudBlobClient();
var container = blobClient.GetContainerReference(ContainerName);
var blob = container. GetBlockBlobReference(BlobName);
blobInfo[0] = blob. Uri.AbsoluteUri;
blobInfo[1] = blob. GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5),
Permissions = SharedAccessBlobPermissions.Read
});
return blobInfo;
}
6. 完成上述代碼以後,就可以對該Azure應用點擊Build->Publish將該服務發佈Windows Azure上去了:
a. 發佈嚮導首先會讓您提供您的Windows Azure帳號,如果您已經登錄過,那麼可以直接在下拉清單中選中,如果您是第一次登錄,那麼需要按Sign In按鈕輸入帳號資訊。 然後按Next進入下一頁:
b. 如果您的Windows Azure上沒有創建過Cloud Service,那麼您需要創建一個新的Cloud Service,並且設定伺服器位置。 或者您也可以選擇覆蓋一個已有的Cloud Service。 這裡我們將新建的Cloud Service取名為SASService:
c. 完成設置之後,發佈嚮導會將該Cloud Service及應用部署到您的Windows Azure上去,您可以通過Windows Azure監管中心確認該Cloud Service以及應用是否已經部署成功。 當Cloud Service部署完成後,Service Status會顯示Created, Production會顯示Running:
d. 點擊該Cloud service的URL進入提供WCF Service的網站,我們可以看到,該網站提供的WCF Service是Service1.svc。 所以訪問該WCF Service的URL就是HTTP://sasservice.cloudapp.net/Service1.svc。
e. 打開這個URL,確認該WCF Service可用,並且可以得到在用戶端調用該服務的C#示例代碼。