使用共用金鑰進行授權

除非要求適用于已提供給公用或已簽署存取的 Blob 或容器資源,否則對儲存體服務提出的每個要求都必須獲得授權。 授權要求的其中一個選項是使用共用金鑰,如本文所述。

提示

Azure 儲存體支援與Azure Active Directory整合,以更精細地控制對儲存體資源的存取。 Blob 和佇列服務支援 Azure AD 整合。 因為 Azure AD 提供身分識別管理,所以您可以授權存取儲存體資源,而不需在應用程式中儲存帳戶存取金鑰,就像使用共用金鑰一樣。 如需詳細資訊,請參閱使用 Azure Active Directory 授權

Blob、佇列、資料表和檔案服務支援下列 2009-09-19 版和 (更新版本的共用金鑰授權配置,以及 Blob、佇列和資料表服務) 版本和 2014-02-14 版和更新版本的 (共用金鑰授權配置) :

  • Blob、佇列和檔案服務的共用金鑰。 使用共用金鑰授權配置,對 Blob、佇列和檔案服務提出要求。 2009-09-19 版和更新版本中的共用金鑰授權支援增強型簽章字串,以增強安全性,且要求您更新服務以使用此增強簽章授權。

  • 表格服務的共用金鑰。 使用共用金鑰授權配置,以使用 REST API 對資料表服務提出要求。 在 2009-09-19 版和更新版本中,資料表服務的共用金鑰授權會使用與舊版資料表服務相同的簽章字串。

  • 共用金鑰 Lite。 使用共用金鑰 Lite 授權配置對 Blob、佇列、資料表和檔案服務提出要求。

    對於 2009-09-19 版和更新版本的 Blob 和佇列服務,共用金鑰 Lite 授權支援使用與舊版 Blob 和佇列服務中共用金鑰支援的簽章字串相同。 因此,您可以使用共用金鑰 Lite 對 Blob 和佇列服務提出要求,而不需要更新您的簽章字串。

授權的要求需要兩個標頭: Datex-ms-date 標頭和 Authorization 標頭。 下列各節說明如何建構這些標頭。

重要

Azure 儲存體支援 HTTP 和 HTTPS,但強烈建議使用 HTTPS。

注意

設定容器的權限即可將容器或 Blob 設為公開存取。 如需詳細資訊,請參閱管理Azure 儲存體資源的存取權。 容器、Blob、佇列或資料表可透過共用存取簽章取得已簽署的存取權;共用存取簽章是透過不同的機制授權。 如需詳細資訊 ,請參閱使用共用存取簽章委派存取 權。

指定 Date 標頭

所有授權的要求都必須包含要求的國際標準時間 (UTC) 時間戳記。 您可以使用 x-ms-date 標頭或標準 HTTP/HTTPS Date 標頭以指定時間戳記。 如果在要求中同時指定這兩個標頭,則會使用 x-ms-date 的值做為要求的建立時間。

儲存體服務會確保要求從提出到送抵服務的時間不超過 15 分鐘。 如此可防止特定安全性攻擊,包括重新執行攻擊。 當此檢查失敗時,伺服器會傳回回應碼 403 (禁止)。

注意

提供 x-ms-date 標頭的原因是某些 HTTP 用戶端程式庫和 Proxy 會自動設定 Date 標頭,而且不會讓開發人員有機會讀取其值,以便在授權的要求中包含它。 如果設定 x-ms-date,請使用 Date 標頭的空值建構簽章。

指定授權標頭

授權的要求必須包含 Authorization 標頭。 如果未包含此標頭,則要求為匿名,而且只有針對標示為公開存取的容器或 Blob,或是針對已提供共用存取簽章來進行委派存取的容器、Blob、佇列或資料表,才會成功。

若要授權要求,您必須使用提出要求的帳戶金鑰簽署要求,並將該簽章當做要求的一部分傳遞。

Authorization 標頭的格式如下:

Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"  

其中 SharedKeySharedKeyLite 是授權配置的名稱,AccountName 是要求資源的帳戶名稱,而 Signature 是雜湊式訊息驗證碼 (Hash-based Message Authentication Code,HMAC),此驗證碼從要求建構而來,並使用 SHA256 演算法計算,然後使用 Base64 編碼方式進行編碼。

注意

如果可以公開存取資源,則可要求位於不同帳戶下的資源。

下列各節說明如何建構 Authorization 標頭。

建構簽章字串

建構簽章字串的方式取決於您要授權的服務與版本,以及您使用的授權配置。 建構簽章字串時,請注意下列事項:

  • 字串的 VERB 部分為 HTTP 動詞命令 (例如 GET 或 PUT),且必須使用大寫。

  • 對於 Blob、佇列和檔案服務的共用金鑰授權,簽章字串中包含的每個標頭可能只會顯示一次。 如有任何重複的標頭,服務會傳回狀態碼 400 (不正確的要求)。

  • 所有標準 HTTP 標頭的值必須依照簽章格式中所示的順序加入字串,但不包括標頭名稱。 這些標頭若未指定為要求的一部分,則為空白,在此情況下,只有新行字元是必要項目。

  • 如果 x-ms-date 標頭已指定,不論是否在要求中指定 Date 標頭,都可以將其忽略,並直接為簽章字串的 Date 部分指定空行。 在此情況下,請遵循 建構標準標頭字串區 段中的指示來新增 x-ms-date 標頭。

    可以同時 x-ms-date 指定 和 Date ,在此情況下,服務會使用 的值 x-ms-date

  • 如果未指定 x-ms-date 標頭,請在簽章字串中指定 Date 標頭,但不包括標頭名稱。

  • 在簽章字串中,所有顯示的新行字元 (\n) 都是必要項目。

  • 簽章字串包含正式標頭和正式資源字串。 標準化這些字串,可使其成為 Azure 儲存體可辨識的標準格式。 如需組成部分簽章字串之 CanonicalizedHeadersCanonicalizedResource 字串建構的詳細資訊,請參閱本主題後的適當章節。

Blob、佇列和檔案服務 (共用金鑰授權)

若要對 2009-09-19 版及更新版本的 Blob 或佇列服務,或 2014-02-14 版及更新版本的檔案服務提出要求的共用金鑰簽章字串進行編碼,請使用下列格式:

StringToSign = VERB + "\n" +  
               Content-Encoding + "\n" +  
               Content-Language + "\n" +  
               Content-Length + "\n" +  
               Content-MD5 + "\n" +  
               Content-Type + "\n" +  
               Date + "\n" +  
               If-Modified-Since + "\n" +  
               If-Match + "\n" +  
               If-None-Match + "\n" +  
               If-Unmodified-Since + "\n" +  
               Range + "\n" +  
               CanonicalizedHeaders +   
               CanonicalizedResource;  

重要

在目前版本中,如果要求的內容長度為零,Content-Length 欄位必須是空字串。 在 2014-02-14 版和更早版本中,即使為零,也包含內容長度。 如需舊行為的詳細資訊,請參閱下方。

下列範例顯示 取得 Blob 作業的簽章字串。 如果沒有標頭值,則只會指定分行符號。

GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer\ncomp:metadata\nrestype:container\ntimeout:20  

將此程式碼逐行細分會顯示相同字串的每個部分:

GET\n /*HTTP Verb*/  
\n    /*Content-Encoding*/  
\n    /*Content-Language*/  
\n    /*Content-Length (empty string when zero)*/  
\n    /*Content-MD5*/  
\n    /*Content-Type*/  
\n    /*Date*/  
\n    /*If-Modified-Since */  
\n    /*If-Match*/  
\n    /*If-None-Match*/  
\n    /*If-Unmodified-Since*/  
\n    /*Range*/  
x-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n    /*CanonicalizedHeaders*/  
/myaccount /mycontainer\ncomp:metadata\nrestype:container\ntimeout:20    /*CanonicalizedResource*/  

下一步,使用 HMAC-SHA256 演算法將此字串編碼,以覆寫 UTF-8 編碼的簽章字串,然後建構 Authorization 標頭,再將標頭加入要求。 下列範例顯示相同作業的 Authorization 標頭:

Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=  

若要搭配 2009-09-19 版和更新版本的 Blob 和佇列服務使用共用金鑰授權,您必須更新程式碼以使用此增強簽章字串。

如果您想要將程式碼移轉至 2009-09-19 版或更新版本的 Blob 和佇列服務,但可能最少的變更,您可以修改現有的 Authorization 標頭以使用共用金鑰 Lite,而不是共用金鑰。 若為 2009-09-19 版之前的 Blob 和佇列服務版本,共用金鑰 Lite 所需的簽章格式與共用金鑰所需的簽章格式完全相同。

重要

如果您要在已啟用讀取權限異地複寫 (RA-GRS) 的儲存體帳戶中存取次要位置,請勿在授權標頭中包含 -secondary 指定。 對於授權目的,帳戶名稱一律是主要位置的名稱,即使是次要存取也一樣。

2014-02-14 版和更早版本中的內容長度標頭

使用 2014-02-14 版或更早版本時,如果 Content-Length 為零,請將 的 StringToSign 部分設定 Content-Length0 。 這通常是空字串。

例如,針對下列要求,即使標頭為零,標頭的值 Content-Length 也會包含在 StringToSign 中。

PUT http://myaccount/mycontainer?restype=container&timeout=30 HTTP/1.1  
x-ms-version: 2014-02-14  
x-ms-date: Fri, 26 Jun 2015 23:39:12 GMT  
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=  
Content-Length: 0

StringToSign建構如下:

Version 2014-02-14 and earlier:
PUT\n\n\n\n0\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2014-02-14\n/myaccount/mycontainer\nrestype:container\ntimeout:30

而在 2014-02-14 之後的版本中 StringToSign ,必須包含 的 Content-Length 空字串:

Version 2015-02-21 and later:
PUT\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer\nrestype:container\ntimeout:30

資料表服務 (共用金鑰授權)

如果您的服務使用 REST API 提出要求,您必須使用共用金鑰授權來授權對資料表服務提出的要求。 針對表格服務所使用的共用金鑰簽章字串之格式,在所有版本中完全相同。

資料表服務要求的共用金鑰簽章字串與 Blob 或佇列服務的要求稍有不同,因為它不包含 CanonicalizedHeaders 字串的部分。 此外,在此情況下的 Date 標頭永遠不會是空白,即使要求設定 x-ms-date 標頭亦然。 如果要求設定 x-ms-date,也會使用該值做為 Date 標頭的值。

針對使用 REST API 對表格服務提出要求的簽章字串,若要將其編碼,請使用下列格式:

StringToSign = VERB + "\n" +
               Content-MD5 + "\n" +
               Content-Type + "\n" +  
               Date + "\n" +  
               CanonicalizedResource;  

注意

從 2009-09-19 版開始,表格服務要求所有 REST 呼叫都需包含 DataServiceVersionMaxDataServiceVersion 標頭。 如需詳細資訊 ,請參閱設定 OData 資料服務版本標頭

Blob、佇列和檔案服務 (共用金鑰 Lite 授權)

您可以使用共用金鑰 Lite 授權來授權針對 Blob 和佇列服務的 2009-09-19 版本和更新版本,以及 2014-02-14 版和更新版本的檔案服務所提出的要求。

共用金鑰 Lite 的簽章字串與 2009-09-19 之前 Blob 和佇列服務版本中共用金鑰授權所需的簽章字串相同。 因此,如果您想要移轉具有 Blob 和佇列服務版本 2009-09-19 最小變更的程式碼,您可以修改程式碼以使用共用金鑰 Lite,而不需變更簽章字串本身。 藉由使用共用金鑰 Lite,您將不會取得使用 2009-09-19 版和更新版本共用金鑰所提供的增強式安全性功能。

若要對 Blob 或佇列服務提出要求的簽章字串進行編碼,請使用下列格式:

StringToSign = VERB + "\n" +  
               Content-MD5 + "\n" +  
               Content-Type + "\n" +  
               Date + "\n" +  
               CanonicalizedHeaders +   
               CanonicalizedResource;  

下列範例顯示 Put Blob 作業的簽章字串。 請注意,Content-MD5 標頭行是空白的。 字串中顯示的標頭是名稱/值組,可指定新 Blob 的自訂中繼資料值。

PUT\n\ntext/plain; charset=UTF-8\n\nx-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n/testaccount1/mycontainer/hello.txt  

下一步,使用 HMAC-SHA256 演算法將此字串編碼,以覆寫 UTF-8 編碼的簽章字串,然後建構 Authorization 標頭,再將標頭加入要求。 下列範例顯示相同作業的 Authorization 標頭:

Authorization: SharedKeyLite myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=  

資料表服務 (共用金鑰 Lite 授權)

您可以使用共用金鑰 Lite 授權來授權針對任何資料表服務版本提出的要求。

若要使用共用金鑰 Lite 對針對表格服務所提出之要求的簽章字串進行編碼,請使用下面格式:

StringToSign = Date + "\n"
               CanonicalizedResource  

下列範例顯示 建立資料表 作業的簽章字串。

Sun, 11 Oct 2009 19:52:39 GMT\n/testaccount1/Tables  

下一步,使用 HMAC-SHA256 演算法將此字串編碼,然後建構 Authorization 標頭,再將標頭加入要求。 下列範例顯示相同作業的 Authorization 標頭:

Authorization: SharedKeyLite testaccount1:uay+rilMVayH/SVI8X+a3fL8k/NxCnIePdyZSkqvydM=  

建構標準標頭字串

若要建構簽章字串的 CanonicalizedHeaders 部分,請遵循下列步驟:

  1. 擷取開頭為 x-ms- 的所有資源標頭,包括 x-ms-date 標頭。

  2. 將每個 HTTP 標頭名稱轉換成小寫。

  3. 以辭典編纂順序,依標頭名稱將標頭排序,採用遞增順序。 每個標頭在字串中只能出現一次。

    注意

    語彙排序 不一定與傳統字母順序一致。

  4. 以單一空格取代標頭值中的任何線性空白字元。

線性空白字元包含歸位字元/換行字元 (CRLF) 、空格和索引標籤。 如需詳細資訊 ,請參閱 RFC 2616 第 4.2 節 。 請勿取代引號字串內的任何空白字元。

  1. 修剪標頭中冒號周圍的任何空白字元。

  2. 最後,將新行字元附加至產生清單中的每個正式標頭。 將此清單中的所有標頭串連成單一字串,以建構 CanonicalizedHeaders 字串。

下列範例顯示標準化的標頭字串:

x-ms-date:Sat, 21 Feb 2015 00:48:38 GMT\nx-ms-version:2014-02-14\n

注意

在服務 2016-05-31 版之前,簽章字串會省略具有空白值的標頭。 這些現在會以 CanonicalizedHeaders 表示,方法是緊接在終止新行的冒號字元後面。

建構標準資源字串

簽章字串的 CanonicalizedResource 部分代表此要求以儲存體服務資源為目標。 從資源的 URI 衍生之 CanonicalizedResource 字串的任何部分,都應該以其在 URI 中的相同方式進行編碼。

CanonicalizedResource 字串支援兩種格式:

  • 支援 2009-09-19 版和更新版本 Blob 和佇列服務共用金鑰授權的格式,以及 2014-02-14 版和更新版本的檔案服務。

  • 支援所有版本的表格服務之共用金鑰和共用金鑰 Lite,以及 2009-09-19 版及更新版本 Blob 和佇列服務之共用金鑰 Lite 的格式。 此格式與舊版儲存體服務所使用的格式完全相同。

若要針對您所存取的資料建構之 URI 的協助,請參閱下列主題:

重要

如果儲存體帳戶以讀取權限異地複寫 (RA-GRS) 進行複寫,而且您要存取次要位置中的資源,請勿在 –secondary 字串中包含 CanonicalizedResource 指定。 用於 CanonicalizedResource 字串 URI 中的資源 URI 應該是主要位置之資源的 URI。

注意

如果您要對儲存體模擬器進行授權,帳戶名稱會在字串中 CanonicalizedResource 出現兩次。 這是預期行為。 如果您要對 Azure 儲存體服務進行授權,帳戶名稱只會在字串中 CanonicalizedResource 出現一次。

2009-09-19 和更新版本的共用金鑰格式

此格式支援 2009-09-19 版和更新版本的 Blob 和佇列服務的共用金鑰授權,以及 2014-02-14 版和更新版本的檔案服務。 請依下列方式,以此格式建構 CanonicalizedResource 字串:

  1. 以空白字串 ("") 開頭並附加正斜線 (/),後面接著擁有存取資源的帳戶名稱。

  2. 附加資源的編碼 URI 路徑,不包括任何查詢參數。

  3. 擷取資源 URI 中的所有查詢參數,包括 comp 參數 (如果存在)。

  4. 將所有參數名稱轉換成小寫。

  5. 以辭典編纂順序,依參數名稱將查詢參數排序,採用遞增順序。

  6. 將每個查詢參數名稱和值進行 URL 解碼。

  7. 在每個名稱/值組之前,請包含新行字元 (\n) 。

  8. 以下列格式將每個查詢參數名稱和值附加至字串,並確保名稱和值之間包含冒號 (:):

    parameter-name:parameter-value

  9. 如果查詢參數包含多個值,請依辭典編纂順序將所有的值排序,然後將這些值加入逗號分隔清單中:

    parameter-name:parameter-value-1,parameter-value-2,parameter-value-n

請注意下列建構正式資源字串的規則:

  • 避免在查詢參數值中使用新行字元 (\n)。 如果必須使用,請確定不會影響正式資源字串的格式。

  • 避免在查詢參數值中使用逗號。

下列是一些範例,顯示簽章字串的 CanonicalizedResource 部分,其建構來源可能是給定的要求 URI:

Get Container Metadata  
   GET http://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=metadata
CanonicalizedResource:  
    /myaccount/mycontainer\ncomp:metadata\nrestype:container  
  
List Blobs operation:  
    GET http://myaccount.blob.core.windows.net/container?restype=container&comp=list&include=snapshots&include=metadata&include=uncommittedblobs  
CanonicalizedResource:  
    /myaccount/mycontainer\ncomp:list\ninclude:metadata,snapshots,uncommittedblobs\nrestype:container  
  
Get Blob operation against a resource in the secondary location:  
   GET https://myaccount-secondary.blob.core.windows.net/mycontainer/myblob  
CanonicalizedResource:  
    /myaccount/mycontainer/myblob

2009-09-19 和更新版本的共用金鑰Lite 和資料表服務格式

此格式支援所有版本表格服務的共用金鑰和共用金鑰 Lite,以及 2009-09-19 版及更新版本 Blob 和佇列服務,與 2014-02-14 版及更新版本檔案服務的共用金鑰 Lite。 此格式與舊版儲存體服務所使用的格式完全相同。 請依下列方式,以此格式建構 CanonicalizedResource 字串:

  1. 以空白字串 ("") 開頭並附加正斜線 (/),後面接著擁有存取資源的帳戶名稱。

  2. 附加資源的編碼 URI 路徑。 如果要求 URI 指向某個資源元件,請附加適當的查詢字串。 查詢字串應該包含問號和 comp 參數 (例如 ?comp=metadata)。 查詢字串中不應該包含其他參數。

編碼簽章

若要對簽章進行編碼,請對 UTF-8 編碼的簽章字串呼叫 HMAC-SHA256 演算法,並將結果編碼為 Base64。 請注意,您也需要 Base64 解碼儲存體帳戶金鑰。 請使用下列格式 (顯示為虛擬程式碼):

Signature=Base64(HMAC-SHA256(UTF8(StringToSign), Base64.decode(<your_azure_storage_account_shared_key>)))  

另請參閱