網站搜尋

javascript - 為 Azure API 管理建立的 SAS 令牌無效


我正在嘗試使用 JavaScript(Express.js)創建一個 SAS Token 來與 Azure API 管理 Rest API 通訊。但使用這個實際上導致我遇到 401 Unauthorized。我正在使用以下程式碼行。

//  setting one day expiry time
const expiryDate = new Date(Date.now() + 1000 * 60 * 60 * 24)
const expiryString = expiryDate.toISOString()

const identifier = process.env.AZURE_APIM_IDENTIFIER
const key = process.env.AZURE_APIM_SECRET_KEY ?? ""

const stringToSign = `${identifier}\n${expiryString}`

const signature = CryptoJS.HmacSHA256(stringToSign, key)
const encodedSignature = CryptoJS.enc.Base64.stringify(signature)
    
//  SAS Token
const sasToken = `SharedAccessSignature uid=${identifier}&ex=${expiryString}&sn=${encodedSignature}`

上面的程式碼片段返回給我類似這樣的東西:SharedAccessSignature uid=integration&ex=2021-04-21T10:48:04.402Z&sn=**O8KZAh9zVHw6Dmb03t1xlhTnrmP1B6i+5lbhQWe**=(為了安全起見部分字符被隱藏,但字符數量是真實的)

請注意,上述的 SAS 令牌中僅有一個尾隨的 連字符 =,而所有範例中的 SAS 令牌以及從 API 管理入口手動創建的 SAS 令牌都有兩個 連字符 ==

我有做錯什麼嗎?

提前感謝。

答案#1

根據 Azure APIM 的 SAS 令牌文件,我們可以看到範例是 C# 代碼:

範例與你的程式碼之間的差異在於,C# 範例使用 HMACSHA512,但你的程式碼使用 HMAS256。所以我認為你在 nodejs 中也需要使用 HMACSHA512。你可以這樣做:

var hash = crypto.createHmac('sha512', key);

你可能還需要執行 hash.update(text); 和 hash.digest(),請參考這份文件。

答案#2

謝謝 Hury Shen!我也發現我們不需要 crypto-js(因為我們必須為此導入外部庫)。Node 有 crypto 作為其原生模組,我們可以使用它。以下的 JavaScript 代碼段運行良好。

import crypto from "crypto"

const identifier = <YOUR_AZURE_APIM_IDENTIFIER>
const secretKey = <YOUR_AZURE_APIM_SECRET_KEY>

//  setting token expiry time
const expiryDate = new Date(Date.now() + 1000 * 60 * 60 * 24 * 29)
const expiryString = expiryDate.toISOString().slice(0, -1) + "0000Z"

const dataToSign = `${identifier}\n${expiryString}`

//  create signature
const signedData = crypto
    .createHmac("sha512", secretKey)
    .update(dataToSign)
    .digest("base64")

//  SAS Token
const accessToken = `SharedAccessSignature uid=${identifier}&ex=${expiryString}&sn=${signedData}`