向 Azure Blob 存储发出 GET 请求时授权失败 [REST API][Azure Blob 存储]

Posted

技术标签:

【中文标题】向 Azure Blob 存储发出 GET 请求时授权失败 [REST API][Azure Blob 存储]【英文标题】:Authorization Failed while making GET Request to Azure Blob Storage [REST API][Azure Blob Storage] 【发布时间】:2021-05-31 17:55:24 【问题描述】:

我正在尝试发出 GET 请求以获取我的 Azure Blob 存储帐户的帐户详细信息,但它每次都显示 Auth 失败。 任何人都可以判断形成的 Header 或 Signature String 是否正确或是否有任何其他问题?

代码如下:

const account = process.env.ACCOUNT_NAME || "";
const key = process.env.ACCOUNT_KEY || "";

var strTime = new Date().toUTCString();
var strToSign =
  "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" +
  strTime +
  `\nx-ms-version:2018-03-28\n/$account/\ncomp:properties\nrestype:account`;
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey $account:$hashInBase64`;

const options = 
  url: `https://$account.blob.core.windows.net/?comp=properties&restype=account`,

  headers: 
    Authorization: auth,
    "x-ms-date": strTime,
    "x-ms-version": "2018-03-28",
  ,
;

function callback(error, response, body) 
  var json = parser.toJson(body);
  console.log(error);
  console.log(response);
  if (!error && response.statusCode == 200) 
    var json = parser.toJson(body);
    console.log(json);
  


request(options, callback);

在此之后,我得到的 response.statusCode 是状态 403。

statusCode: 403,
statusMessage: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.',

可以在此处找到有关 azure-blob 和标头以及身份验证的详细信息: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key

https://docs.microsoft.com/en-us/rest/api/storageservices/get-account-information

编辑: 字符串参数= 已更正为:

【问题讨论】:

【参考方案1】:

using Azure Storage JS SDK 向 Azure Blob 存储发出请求会容易得多。如果您想获取您的存储帐户信息,只需尝试以下代码:

const  BlobServiceClient, StorageSharedKeyCredential  = require("@azure/storage-blob");

const account = '<storage account name>'
const accountKey = '<storage account key>'

const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);

const blobServiceClient = new BlobServiceClient(
    `https://$account.blob.core.windows.net`,
    sharedKeyCredential
);

blobServiceClient.getAccountInfo().then((result)=>
    console.log("accountKind:"+result.accountKind + " skuName:" + result.skuName + " version:" + result.version );
)

结果:

更新:

如果您想以更通用的方式进行尝试,请尝试以下代码:

var CryptoJS = require("crypto-js");
var request = require("request");
var parser = require('body-parser')

const account = ''
const key = ''

var strTime = new Date().toUTCString();
var strToSign =
  "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" +
  strTime +
  `\nx-ms-version:2018-03-28\n/$account/\ncomp:properties\nrestype:account`;

  //console.log(strToSign);
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey $account:$hashInBase64`;

const options = 
  url: `https://$account.blob.core.windows.net/?comp=properties&restype=account`,

  headers: 
    Authorization: auth,
    "x-ms-date": strTime,
    "x-ms-version": "2018-03-28",
  ,
;

function callback(error, response, body) 
 
  console.log(body);
  if (!error && response.statusCode == 200) 
    
    console.log(response.headers["x-ms-sku-name"]);
  


request(options, callback);

结果:

看来您应该在 strToSign 的最后一个参数中使用 : 而不是 =

【讨论】:

是的,我已经使用 Azure 存储 SDK 进行了尝试,它可以工作,但我想以更通用的方式进行尝试。因此无法使用 Azure SDK。谢谢。 @MayankPatel,我已经更新了我的答案,如果它对您有帮助,您能否单击答案旁边的复选标记将其从灰色切换为已填写以接受它作为答案? 谢谢,@Stanley 似乎解决了获取帐户信息的问题。但是我遇到了另一个问题,获取容器详细信息。我使用的资源字符串是: var strToSign = "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" + strTime + \nx-ms-version:2018-03-28\n/$account/demo?restype:container ;和 url 是:https://$account.blob.core.windows.net/demo?restype=container 有什么重要的我错过了。 @MayankPatel,您能否打开一个新问题并告诉我它的链接? 嗨,这个问题目前已解决我遇到了另一个与使用 REST API 将数据作为流上传到 azure blob 相关的问题。这是问题的链接,请看一下。 Link

以上是关于向 Azure Blob 存储发出 GET 请求时授权失败 [REST API][Azure Blob 存储]的主要内容,如果未能解决你的问题,请参考以下文章

请求令牌时如何在 Azure 存储 Blob 中为 REST 请求指定范围? [AZURE-BLOB][REST API]

Azure rest api 放置 blob

如何将自定义响应标头添加到来自 azure blob 的响应?

在 Azure 存储 [REST] [Azure Blob] 中对 PUT Blob 的 REST api 调用中的身份验证失败

为 Azure Blob 存储批量更改层

Azure APIM 在预检和从 axios 发出的 GET 请求时返回空响应正文,状态代码为 200