我在尝试使用 Azure Blob Rest API 获取有效身份验证时遇到问题。我正在使用帐户名、帐户密钥和容器名称,简而言之,使用共享密钥进行身份验证,但每次尝试时都会出现此错误。
:状态 403 :reason-phrase 服务器未能验证请求。确保授权标头的值格式正确,包括签名。 请求中的日期标头不正确。
这是我的代码:
(require '[clj-http.client :as http])
(require '[java-time :as jt])
(import javax.crypto.Mac
javax.crypto.spec.SecretKeySpec
org.apache.commons.codec.binary.Base64)
(defn- canonicalized-resource [account-name container-name blob-name]
(str "/" account-name "/" container-name "/" blob-name))
(defn get-authorization-header
"Returns the Authorization header for a Blob Storage request."
[account-name account-key request-date request-method content-type canonicalized-resource version]
(let [string-to-sign (str request-method "\n\n\n\n\n"
content-type "\n"
"\n\n\n\n\n\n"
"x-ms-date:" request-date "\n"
"x-ms-version:" version "\n"
canonicalized-resource)
key-bytes (Base64/decodeBase64 account-key)
key-spec (SecretKeySpec. key-bytes "HmacSHA256")
mac (Mac/getInstance "HmacSHA256")
_ (.init mac key-spec)
signature-bytes (.doFinal mac (.getBytes string-to-sign))
signature (Base64/encodeBase64String signature-bytes)
auth-header (str "SharedKey " account-name ":" signature)]
auth-header))
(defn put-blob [account-name account-key container-name blob-name content-type file-path]
(let [request-date (jt/format (jt/formatter :rfc-1123-date-time) (jt/zoned-date-time (jt/zone-offset 0)))
version "2022-11-02"
request-url (str "https://" account-name ".blob.core.windows.net/" container-name "/" blob-name)
canon-resource (canonicalized-resource account-name container-name blob-name)
auth-header (get-authorization-header account-name account-key request-date "PUT" content-type canon-resource version)
file-content (slurp file-path)
response (http/put request-url
{:body (Base64/encodeBase64 (.getBytes file-content))
:content-type content-type
:headers {"Content-Type" content-type
"x-ms-date" request-date
"x-ms-version" version
"x-ms-blob-type" "BlockBlob"
"Authorization" auth-header}
:debug true})]
(if (= (:status response) 201)
(:body response)
(throw (Exception. (:body response))))))
我浏览了有关使用共享密钥授权和放置操作的文档。
我错过了什么?