Golang 實現華為雲 DMS 簽名

  • 2019 年 11 月 5 日
  • 筆記

構造請求

首先構造請求,也就是要對哪個具體介面進行訪問,需要提供什麼必要的參數。在構造請求(點擊查看中可以看到,對 DMS 服務來說必要的請求構成包括以下部分

  • 請求URI,例如 https://dms.cn-north-1.myhuaweicloud.com/v1.0/{project_id}/queues/{quque_id}(不同區域的Region部分不同)
  • 請求方法,如 "GET"、"POST"
  • 請求消息頭,必選的是 "Content-Type",規定了消息體的格式,默認取值 "application/json",即消息體 "Body" 以 Json 格式提交
  • 請求消息體,有的介面需要,有的介面不需要

準備參數

以介面查看指定隊列(點擊查看)為例

  • 請求URI:https://dms.cn-north-1.myhuaweicloud.com/v1.0/{project_id}/queues/{quque_id}
  • 請求方法:"GET"
  • 請求消息體:無
  • project_id:項目ID,去統一身份認證的項目中根據區域不同查找
  • queue_id:要訪問的隊列ID,去控制台點開該隊列查看
  • AK/SK:秘鑰對,在統一身份認證內的用戶的安全設置功能中管理,是生成簽名的必需參數

計算簽名

以AK/SK簽名認證演算法詳解(點擊查看)為標準,編寫演算法或使用 SDK,本例中使用的是官方提供的 SDK,調用步驟如下(點擊查看

生成 HTTP 請求

以 AK=ABCDE….WYZ 和 SK=123…890為例,使用 SDK 生成簽名

/*  查看指定隊列  */  url := "https://dms.cn-north-1.myhuaweicloud.com/v1.0/506d66e5/queues/bc8e-86-42-8c-4d2"  r, err := http.NewRequest(      "GET",      url,      ioutil.NopCloser(bytes.NewBuffer([]byte(""))))  /*  添加必要的 Content-Type 頭  */  r.Header.Add("content-type", "application/json")  /*  創建簽名對象並簽名  */  s := sign.Signer{ Key:conf.AK, Secret:conf.SK}  s.Sign(r)

s.Sign(r) 方法將兩個請求頭添加到了 r.Headers 中,一個是 X-Sdk-Date 其值是時間戳,另一個是 Authorization 其值是經過規定方式計算並拼接的一串字元串,如果將 r.Headers 列印出來就是

map[Authorization:[SDK-HMAC-SHA256 Access=ABCDE....WYZ, SignedHeaders=content-type;x-sdk-date, Signature=0e9d22d370b3b34b6108998c3ced1d99cdb6d813aa41b5efeb7828295bb8f7a8] Content-Type:[application/json] X-Sdk-Date:[20191105T083411Z]]

所有參數均已齊備,整理一下本次請求的所有內容

  • 請求完整URI:https://dms.cn-north-1.myhuaweicloud.com/v1.0/506d66e5/queues/bc8e-86-42-8c-4d2
  • 請求頭
    • Content-Type:application/json
    • X-Sdk-Date:20191105T083411Z
    • Authorization:SDK-HMAC-SHA256 Access=ABCDE….WYZ, SignedHeaders=content-type;x-sdk-date, Signature=0e9d22d370b3b34b6108998c3ced1d99cdb6d813aa41b5efeb7828295bb8f7a8
    • 請求體:該介面無請求體,即 http 協議的 body 為空

使用 Postman 提交請求,響應正文如下

{      "id": "bcf28b8e-83e6-4432-870c-413e79e555d2",      "name": "huawei-dms-queue-log-test",      "description": "",      "reservation": 4320,      "created": 1559033038000,      "queue_mode": "KAFKA_HA",      "max_msg_size_byte": 524288,      "produced_messages": 2,      "eff_date": 1559033038000,      "group_count": 1,      "kafka_topic": "k-506dba42b0f146b9a6026653544f66e5-bcf28b8e-83e6-4432-870c-413e79e555d2"  }

簽名比對

以上資訊有的經過了優化處理,屏蔽掉了可能的隱私資訊,如何驗證計算結果正確與否呢。當 AK=ABCDE….WYZSK=123…890X-Sdk-Date=20191105T094500Z 時,簽名結果如下即為正確

Authorization:  SDK-HMAC-SHA256 Access=ABCDE....WYZ, SignedHeaders=content-type;x-sdk-date, Signature=8e0cb2f284b44795eee578d3484217a929cc1d9347bc6445477322eff15f8743

注意

雲服務中尤其是API調用可能涉及很多許可權問題,要檢查所有可能的許可權是否打開,比如當前AK/SK對應的用戶是否是IAM用戶,該用戶所在的用戶組是否被授權了對DMS產品的訪問。在本文編寫前,就碰到了簽名始終報錯 402 的問題,在對IAM帳號所在用戶組賦予了相應的策略後訪問正常,雖然不能100%確認是該原因。