3

我正在尝试创建一个使用 JavaScript (Express.js)SAS TokenAzure API Management 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 令牌都有 2 个 破折号= ==

有什么我做错了吗?

提前致谢。

4

2 回答 2

1

根据Azure APIM 的 SAS token文档,我们可以看到示例是 c# 代码:

在此处输入图像描述

示例和您的代码之间的区别在于 c# 示例使用 HMACSHA512,但您的代码使用 HMAS256。所以我认为你还需要在你的 nodejs 中使用 HMACSHA512。你可以这样做:

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

您可能还需要做hash.update(text);hash.digest(),请参考这个文档

于 2021-04-21T02:28:01.960 回答
1

谢谢你,沉!我还发现我们不需要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}`
于 2021-04-21T23:25:40.947 回答