使用共用金鑰進行授權

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

提示

Azure 記憶體提供與 Microsoft Entra ID的整合,以便對 Blob、檔案、佇列和數據表服務的要求進行身分識別型授權。 透過 Microsoft Entra ID,您可以使用角色型訪問控制 (RBAC) ,將 Blob、檔案、佇列和資料表資源的存取權授與使用者、群組或應用程式。 Microsoft Entra ID 可用來授權存取記憶體資源,而不需在應用程式中儲存您的帳戶存取密鑰,就像使用共用密鑰一樣。 如需詳細資訊,請參閱使用 Microsoft Entra ID 授權

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

另請參閱