使用共用金鑰進行授權

對儲存體服務提出的每個要求都必須獲得授權,除非要求是針對已提供公開或簽署存取權的 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、佇列或資料表可透過共用存取簽章提供簽署存取;共用存取簽章會透過不同的機制獲得授權。 如需詳細資訊,請參閱 使用共用存取簽章來委派存取權

指定日期標頭

所有授權的要求都必須包含要求的國際標準時間 (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 部分指定空行。 In this case, follow the instructions in the Constructing the canonicalized headers string section for adding the x-ms-date header.

    您可以同時指定和, x-ms-dateDate 在此情況下,服務會使用的值 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;  

重要

在目前的版本中,如果要求的內容長度為零,則內容長度欄位必須是空字串。 在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=  

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

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

重要

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

2014-02-14 版和更舊版本中的 content-length 標頭

使用2014-02-14 版或更早版本時,如果 Content-Length 是零,則將的 Content-Length 部分設 StringToSign0 。 一般來說,這會是空字串。

例如,在下列要求中, 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 授權授權對2009-09-19 版及更新版本的 Blob 和佇列服務,以及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  

下列範例會顯示 Create Table 作業的簽章字串。

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 字串支援兩種格式:

  • 一種格式,可支援 Blob 和佇列服務2009-09-19 版和更新版本的共用金鑰授權,以及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>)))  

另請參閱