从 Postman 访问 Azure 存储帐户资源
介绍
Azure 存储帐户提供低成本、高可用性的数据服务。访问这些数据服务的主要方式是使用 REST API。对于您企业的自定义 REST API,您可能已经习惯使用 Postman 来测试、调试和监控它们。如果您可以留在 Postman 中与您的 Azure 存储帐户进行交互,那将会很方便,也许可以简化端到端测试或与您的团队成员共享请求。
在本指南中,您将了解如何使用 Postman 与存储帐户进行交互。您将设置身份验证,然后查询存储表和存储 blob。本指南基于上一个指南“设置 Postman 并自动添加 Bearer 令牌”。
Azure 存储帐户提供多种身份验证方式,包括存储 blob 和存储队列的托管标识、Azure AD 身份验证、共享密钥和共享访问签名 (SAS) 令牌。但是,最简单的解决方案是使用共享密钥。创建存储帐户时会为您提供两个密钥。它们有权在存储帐户上执行所有操作,因此务必小心安全地存储它们。
下面的代码片段展示了如何生成向存储表发出请求所需的授权值。
const storageAccount = pm.variables.get('azure_storage_account');
const accountKey = pm.variables.get('azure_storage_key');
const date = new Date();
const UTCstring = date.toUTCString();
const dataToEncode = UTCstring + "\n" + `/${storageAccount}${pm.request.url.getPath()}`;
const encodedData = unescape(encodeURIComponent(dataToEncode));
var hash = CryptoJS.HmacSHA256(encodedData, CryptoJS.enc.Base64.parse(accountKey));
var signature = hash.toString(CryptoJS.enc.Base64);
var auth = "SharedKeyLite " + storageAccount + ":" + signature;
pm.variables.set("header_authorization", auth);
pm.variables.set("header_date", UTCstring);
将此代码片段设置为预请求脚本后,您还需要设置标题以读取保存的变量。
GET https://{{azure_storage_account}}.table.core.windows.net/MyTable()?$filter=(PartitionKey eq 'PartitionA')
x-ms-date:{{header_date}}
Authorization:{{header_authorization}}
x-ms-version:2019-02-02
Accept:application/json;odata=nometadata
上面的标头详细信息演示了如何配置表存储查询的 URL 和标头。运行此请求时,它将返回与指定过滤器匹配的行的 JSON 列表。
您还可以使用共享密钥连接到 Blob 存储。但是,执行此操作的脚本稍微复杂一些。它如下所示,来源于Kamran Ayub 的 azure-storage-rest-postman GitHub 存储库。
// Set Date header value for authorization
// Should be UTC GMT string
pm.variables.set("header_date", new Date().toUTCString());
// Get hash of all header-name:value
const headers = pm.request.getHeaders({ ignoreCase: true, enabled: true });
// Construct Signature value for Authorization header
var signatureParts = [
pm.request.method.toUpperCase(),
headers["content-encoding"] || "",
headers["content-language"] || "",
headers["content-length"] || "",
// pm.request.body ? pm.request.body.toString().length || "" : "",
headers["content-md5"] || "",
headers["content-type"] || "",
headers["x-ms-date"] ? "" : (pm.variables.get("header_date") || ""),
headers["if-modified-since"] || "",
headers["if-match"] || "",
headers["if-none-match"] || "",
headers["if-unmodified-since"] || "",
headers["range"] || ""
];
// Construct CanonicalizedHeaders
const canonicalHeaderNames = [];
Object.keys(headers).forEach(key => {
if (key.startsWith("x-ms-")) {
canonicalHeaderNames.push(key);
}
});
// Sort headers lexographically by name
canonicalHeaderNames.sort();
const canonicalHeaderParts = [];
canonicalHeaderNames.forEach(key => {
let value = pm.request.getHeaders({ ignoreCase: true, enabled: true })[key];
// Populate variables
value = pm.variables.replaceIn(value);
// Replace whitespace in value but not if its within quotes
if (!value.startsWith("\"")) {
value = value.replace(/\s+/, " ");
}
canonicalHeaderParts.push(`${key}:${value}`);
});
// Add headers to signature
signatureParts.push.apply(signatureParts, canonicalHeaderParts);
// Construct CanonicalizedResource
const canonicalResourceParts = [
`/${pm.variables.get("azure_storage_account")}${pm.request.url.getPath()}`
];
const canonicalQueryNames = [];
pm.request.url.query.each(query => {
canonicalQueryNames.push(query.key.toLowerCase());
});
canonicalQueryNames.sort();
canonicalQueryNames.forEach(queryName => {
const value = pm.request.url.query.get(queryName);
// NOTE: This does not properly explode multiple same query params' values
// and turn them into comma-separated list
canonicalResourceParts.push(`${queryName}:${value}`);
});
// Add resource to signature
signatureParts.push.apply(signatureParts, canonicalResourceParts);
console.log("Signature Parts", signatureParts);
// Now, construct signature raw string
const signatureRaw = signatureParts.join("\n");
console.log("Signature String", JSON.stringify(signatureRaw));
// Hash it using HMAC-SHA256 and then encode using base64
const storageKey = pm.variables.get("azure_storage_key");
const signatureBytes = CryptoJS.HmacSHA256(signatureRaw, CryptoJS.enc.Base64.parse(storageKey));
const signatureEncoded = signatureBytes.toString(CryptoJS.enc.Base64);
console.log("Storage Account", pm.variables.get("azure_storage_account"));
console.log("Storage Key", storageKey);
// Finally, make it available for headers
pm.variables.set("header_authorization",
`SharedKey ${pm.variables.get("azure_storage_account")}:${signatureEncoded}`);
接下来需要设置请求头,类似于上面的表存储示例。
GET https://{{azure_storage_account}}.blob.core.windows.net/?restype=service&comp=properties
x-ms-date:{{header_date}}
Authorization:{{header_authorization}}
x-ms-version:2018-03-28
这将请求 blob 元数据属性。有关标头中可选和必需内容的更多详细信息,请阅读Microsoft 关于使用共享密钥授权的文档。
结论
如上所示,您可以使用 Postman 内部的共享密钥来查询 Azure 存储帐户资源(例如 Blob 和表)。这对于执行端到端 API 测试很有帮助。您可以在自定义 API 上运行 Postman 请求,并通过查询存储帐户来验证一切是否正常。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~