Invalid SAS token being created for Azure API Management

211 views Asked by At

I am trying to create an SAS Token to communicate with Azure API Management Rest API using JavaScript (Express.js). But using that actually leads me to a 401 Unauthorized. I am using the following lines of code.


//  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}`

The above snippet returns me something like this: SharedAccessSignature uid=integration&ex=2021-04-21T10:48:04.402Z&sn=**O8KZAh9zVHw6Dmb03t1xlhTnrmP1B6i+5lbhQWe**= (Some characters hidden for security, but number of characters is real)

Note that there is only one trailing dash = in the above mentioned SAS token, whereas SAS Tokens in all examples and manually created SAS Token from API Management Portal have 2 dashes ==

Is there anything I am doing wrong?

Thanks in advance.

2

There are 2 answers

2
Hury Shen On BEST ANSWER

According to the document of SAS token for Azure APIM, we can see the sample is c# code:

enter image description here

The difference between the sample and your code is the c# sample uses HMACSHA512 but your code use HMAS256. So I think you also need to use HMACSHA512 in your nodejs. You can do it like:

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

You may also need to do hash.update(text); and hash.digest(), please refer to this document about it.

0
danish.ahmad On

Thank you Hury Shen! I also figured out that we don't need crypto-js for (as we have to import an external library for that). Node has crypto as its native module and we can use that. The following JavaScript snippet works fine.

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}`