我需要使用 Javascript 为 azure blob 生成 SAS 令牌。
这是我通过谷歌和文档搜索后编写的代码。
var CryptoJS = require("crypto-js/core")
var blobAccount = 'ACCOUNTNAME';
var blobContainer = 'CONTAINERNAME/PATH_TO_FILE';
var sasToken = '';
var storageAccountKey = 'KEY2';
// Calculate the expiration time
var currentDate = new Date();
var expiration = new Date(currentDate.getTime() + (100 * 365 * 24 * 60 * 60 * 1000));
var st = currentDate.toISOString().slice(0,19)+'Z';
var se = expiration.toISOString().slice(0,19)+'Z';
var sv = '2018-11-09';
var sp = 'r';
var sr = 'b';
var canonicalizedResource = "/"+blobAccount+"/"+blobContainer;
var stringToSign = sp+'\n'+st+'\n'+se+'\n'+canonicalizedResource+'\n'+sv+'\n'+sr+'\n'+'\n'+'\n'+'\n'+'\n'+'\n'+'\n'+'\n';
var signature = CryptoJS.HmacSHA256(stringToSign, CryptoJS.enc.Base64.parse(storageAccountKey)).toString(CryptoJS.enc.Base64);
sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv=2018-11-09&sp=r&sr=b"
var url = "https://"+blobAccount+".blob.core.windows.net/"+blobContainer+"?"+"sig="+sasToken
console.log(sasToken);
console.log(url)
我能够生成 url 但是当直接在浏览器中使用时我得到错误
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:1145b24b-201e-005c-3b3b-86f4f3000000 Time:2023-05-14T08:10:23.2762870Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2023-05-14T08:09:57Z 2123-04-20T08:09:57Z /blob/ACCOUNTNAME/CONTAINERNAME/PATH_TO_FILE 2018-11-09 b </AuthenticationErrorDetail>
</Error>
我尝试了很多组合来创建 stringToSign,我似乎不知道我哪里出错了。我真的希望有人能帮我解决这个问题。我在这里屏蔽了 ACCOUNTNAME、CONTAINERNAME、PATH_TO_FILE、KEY2,但您可以假设它的值。 我的用例是在 servicenow 的业务规则中使用此代码,并使用 cryptoJS 模块作为脚本包含。但那是在这段代码开始生成正确的 URL 之后。
请尝试更改以下代码行:
var sr = 'b';
var canonicalizedResource = "/"+blobAccount+"/"+blobContainer;
到
//this indicates that the signed resource is a blob container
var sr = 'c';
//need to prefix your canonicalized resource with service type i.e. blob.
var canonicalizedResource = "/blob/"+blobAccount+"/"+blobContainer;
同时更改以下代码行:
sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv=2018-11-09&sp=r&sr=b"
到
sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv=2018-11-09&sp=r&sr=c"
我能够解决这个问题。 在为 stringToSign 再次研究网络后,我了解了它的格式
String stringToSign= "rl\n"+ start +"\n" + expiry+ "\n"+ "/blob/"+accountName+"/CONTAINER/PATH_TO_FILE\n"+ "\n"+ "\n"+ "\n"+ azureApiVersion+"\n"+ "b\n"+"\n"+"\n"+"\n"+"\n"+"\n";
但是我使用的 PATH_TO_FILE 有一个空格,我在创建 stringToSign 之前将其替换为 %20。我删除了那个空间到 %20 转换,它开始工作正常。