Azure Blob 存储 403 身份验证因授权失败 Header
Azure Blob Storage 403 Authentication Failed Due To Authorization Header
问题
我已将一组图像 (blob) 上传到私有 Azure Blob 存储帐户,但当我尝试访问它们时,遇到以下错误。
GET https://<account-name>.blob.core.windows.net/<container-name>/<blob-name> 403 (Server failed
to authenticate the request. Make sure the value of Authorization header is formed correctly
including the signature.)
我上传此数据没有任何问题,因为这是使用 Django 应用程序通过 server-side 完成的。我希望能够使用 client-side JavaScript.
成功检索此上传的 blob 数据
背景
我已经通读并实施了 Microsoft Azure 文档中的步骤,通过使用 Shared Keys 授权访问我的私人帐户。这包括从构造我的签名字符串到使用 HMAC SHA-256 算法散列此数据的所有内容,如上文 link 中所述。
我 运行 Docker 容器上的所有内容,除了试图调用 Get Blob API 的 client-side Vue-based 接口端点,如下所示。
最小可重现示例
引发此错误的代码如下:
// Add imports
const crypto = require('crypto');
const axios = require('axios');
// Set Azure blob storage data
const account = "<azure-blob-storage-private-account-name>"
const version = "2020-04-08"
const blob = "<blob-name>"
const container = "<container-name>"
const blob_uri = `https://${account}.blob.core.windows.net/${container}/${blob}`;
const today = new Date().toGMTString();
// Construct signature string
const CanonicalisedHeaders = `x-ms-date:${today}\nx-ms-version:${version}\n`;
const CanonicalisedResource = `/${account}/${container}/${blob}`;
const StringToSign = `GET\n\n\n\n\n\n\n\n\n\n\n\n` + CanonicalisedHeaders + CanonicalisedResource;
// Hash string using HMAC Sha-256 and encode to base64
const key = "<shared-access-key-in-base64>";
const utf8encoded = Buffer.from(key, 'base64').toString('utf8');
const signature = crypto.createHmac('sha256', utf8encoded).update(StringToSign).digest("base64");
// Construct the headers and invoke the API call
const blob_config = {
headers: {
"Authorization": `SharedKey ${account}:${signature}`,
"x-ms-date": today,
"x-ms-version": version
}
}
await axios.get(blob_uri, blob_config)
.then((data) => console.log(data))
.catch((error) => console.log(error.message));
我试过的
我尝试了以下方法,但其中 none 帮助我解决了手头的问题。
- 更新了 CORS 设置以避免 CORS-related 403 禁止访问问题。
- 重新生成了我的密钥和连接字符串。
- 检查了我的本地机器和我的 Docker 容器上的日期时间设置,以确保它们处于正确的 GMT 时间。
- 已检查我的签名字符串的组件(规范化 headers、资源等)是否根据定义的规则构建 here。
- 通读类似的 Whosebug 和 Azure 论坛帖子以寻找解决方案。
请尝试更改以下代码行:
const utf8encoded = Buffer.from(key, 'base64').toString('utf8');
const signature = crypto.createHmac('sha256', utf8encoded).update(StringToSign).digest("base64");
到
const keyBuffer = Buffer.from(key, 'base64');
const signature = crypto.createHmac('sha256', keyBuffer).update(StringToSign).digest("base64");
我认为您不需要将密钥缓冲区转换为 UTF8 编码字符串。
其他几件事:
- 考虑到您是在浏览器中使用它,因此存在巨大的安全风险,因为您将存储密钥暴露给用户。
- 您直接使用 REST API 而不是使用
Azure Storage Blob SDK
有什么原因吗?
- 在基于浏览器的环境中,您应该使用基于
Shared Access Signature
的授权而不是基于 Shared Access Key
的授权。
问题
我已将一组图像 (blob) 上传到私有 Azure Blob 存储帐户,但当我尝试访问它们时,遇到以下错误。
GET https://<account-name>.blob.core.windows.net/<container-name>/<blob-name> 403 (Server failed
to authenticate the request. Make sure the value of Authorization header is formed correctly
including the signature.)
我上传此数据没有任何问题,因为这是使用 Django 应用程序通过 server-side 完成的。我希望能够使用 client-side JavaScript.
成功检索此上传的 blob 数据背景
我已经通读并实施了 Microsoft Azure 文档中的步骤,通过使用 Shared Keys 授权访问我的私人帐户。这包括从构造我的签名字符串到使用 HMAC SHA-256 算法散列此数据的所有内容,如上文 link 中所述。
我 运行 Docker 容器上的所有内容,除了试图调用 Get Blob API 的 client-side Vue-based 接口端点,如下所示。
最小可重现示例
引发此错误的代码如下:
// Add imports
const crypto = require('crypto');
const axios = require('axios');
// Set Azure blob storage data
const account = "<azure-blob-storage-private-account-name>"
const version = "2020-04-08"
const blob = "<blob-name>"
const container = "<container-name>"
const blob_uri = `https://${account}.blob.core.windows.net/${container}/${blob}`;
const today = new Date().toGMTString();
// Construct signature string
const CanonicalisedHeaders = `x-ms-date:${today}\nx-ms-version:${version}\n`;
const CanonicalisedResource = `/${account}/${container}/${blob}`;
const StringToSign = `GET\n\n\n\n\n\n\n\n\n\n\n\n` + CanonicalisedHeaders + CanonicalisedResource;
// Hash string using HMAC Sha-256 and encode to base64
const key = "<shared-access-key-in-base64>";
const utf8encoded = Buffer.from(key, 'base64').toString('utf8');
const signature = crypto.createHmac('sha256', utf8encoded).update(StringToSign).digest("base64");
// Construct the headers and invoke the API call
const blob_config = {
headers: {
"Authorization": `SharedKey ${account}:${signature}`,
"x-ms-date": today,
"x-ms-version": version
}
}
await axios.get(blob_uri, blob_config)
.then((data) => console.log(data))
.catch((error) => console.log(error.message));
我试过的
我尝试了以下方法,但其中 none 帮助我解决了手头的问题。
- 更新了 CORS 设置以避免 CORS-related 403 禁止访问问题。
- 重新生成了我的密钥和连接字符串。
- 检查了我的本地机器和我的 Docker 容器上的日期时间设置,以确保它们处于正确的 GMT 时间。
- 已检查我的签名字符串的组件(规范化 headers、资源等)是否根据定义的规则构建 here。
- 通读类似的 Whosebug 和 Azure 论坛帖子以寻找解决方案。
请尝试更改以下代码行:
const utf8encoded = Buffer.from(key, 'base64').toString('utf8');
const signature = crypto.createHmac('sha256', utf8encoded).update(StringToSign).digest("base64");
到
const keyBuffer = Buffer.from(key, 'base64');
const signature = crypto.createHmac('sha256', keyBuffer).update(StringToSign).digest("base64");
我认为您不需要将密钥缓冲区转换为 UTF8 编码字符串。
其他几件事:
- 考虑到您是在浏览器中使用它,因此存在巨大的安全风险,因为您将存储密钥暴露给用户。
- 您直接使用 REST API 而不是使用
Azure Storage Blob SDK
有什么原因吗? - 在基于浏览器的环境中,您应该使用基于
Shared Access Signature
的授权而不是基于Shared Access Key
的授权。