我面临使用 AAD 令牌作为身份验证的邮递员获取容器 ACL 和设置容器 ACL REST API 的问题
Posted
技术标签:
【中文标题】我面临使用 AAD 令牌作为身份验证的邮递员获取容器 ACL 和设置容器 ACL REST API 的问题【英文标题】:I am facing issues for Get Container ACL and Set Container ACL REST API using postman using AAD Token as authentication 【发布时间】:2021-12-21 09:08:14 【问题描述】:我在使用 Postman 对 Get Container ACL 进行 REST API 调用时遇到以下错误:
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>ResourceNotFound</Code>
<Message>The specified resource does not exist.
RequestId:35678849-101e-005b-0fa8-d4c9bd000000
Time:2021-11-08T13:53:42.8102881Z</Message>
</Error>
在使用 Postman 对 Set Container ACL 进行 REST 调用时出现以下错误:
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>ResourceNotFound</Code>
<Message>The specified resource does not exist.
RequestId:35688854-101e-005b-12a8-d4c9bd000000
Time:2021-11-08T13:58:12.8507122Z</Message>
</Error>
不确定我缺少的是正确的权限还是正确的参数?
【问题讨论】:
【参考方案1】:我使用AAD Authorization
方法进行了相同的测试,仅 ACL 操作遇到了同样的问题,而其他操作(如列表 blob)都成功了。
正如 @SumanthMarigowda-MSFT 所述,ACL 操作不支持 AAD auth
。你必须使用Shared Key Auth
。
步骤:
如下创建环境变量:
注意:只提供高亮变量的初始值,其他变量留空。
创建请求
https://azure_storage_account.blob.core.windows.net/yourcontainername?restype=container&comp=acl
根据您的要求使用Get/Put
并添加以下内容
headers
:
在 Postman 的 Pre-Request Script
选项卡中添加以下代码:
const crypto = require("crypto-js");
// Set Date header value for authorization
// Should be UTC GMT string
pm.environment.set("header_date", new Date().toUTCString());
console.log("header date", new Date().toUTCString());
var substituteEnvVars = function (varStr)
let match;
let replacedVar = varStr;
while ((match = /\\([^]*?)/g.exec(replacedVar)) !== null )
if (!pm.variables.get(match[1]))
continue;
var envVar = new RegExp(RegExp.escape(match[0]), 'g');
replacedVar = replacedVar.replace(envVar, pm.variables.get(match[1]));
return replacedVar;
;
// 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"] || "",
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);
console.log("key: ", canonicalHeaderNames);
);
// Sort headers lexographically by name
canonicalHeaderNames.sort();
const canonicalHeaderParts = [];
canonicalHeaderNames.forEach(key =>
let value = pm.request.getHeaders( ignoreCase: true, enabled: true )[key];
console.log("value: ",value);
// Populate variables
value = substituteEnvVars(value);
console.log("value: ",value);
// Replace whitespace in value but not if its within quotes
if (!value.startsWith("\""))
value = value.replace(/\s+/, " ");
console.log("value: ",value);
canonicalHeaderParts.push(`$key:$value`);
console.log("canonicalHeaderParts: ",canonicalHeaderParts);
);
// Add headers to signature
signatureParts.push.apply(signatureParts, canonicalHeaderParts);
// Construct CanonicalizedResource
const canonicalResourceParts = [
`/$pm.environment.get("azure_storage_account")$pm.request.url.getPath()`
];
console.log("canonicalResourceParts: ",canonicalResourceParts);
const canonicalQueryNames = [];
pm.request.url.query.each(query =>
canonicalQueryNames.push(query.key.toLowerCase());
console.log("canonicalQueryNames: ",query.key.toLowerCase());
);
canonicalQueryNames.sort();
canonicalQueryNames.forEach(queryName =>
const value = pm.request.url.query.get(queryName);
console.log("canonicalQueryNames: ",value);
// NOTE: This does not properly explode multiple same query params' values
// and turn them into comma-separated list
canonicalResourceParts.push(`$queryName:$value`);
console.log("canonicalResourcePartss: ",canonicalResourceParts);
);
// 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.environment.get("azure_storage_key");
const signatureBytes = crypto.HmacSHA256(signatureRaw, crypto.enc.Base64.parse(storageKey));
const signatureEncoded = signatureBytes.toString(crypto.enc.Base64);
console.log("Storage Account", pm.environment.get("azure_storage_account"));
console.log("Storage Key", storageKey);
// Finally, make it available for headers
pm.variables.set("header_authorization",
`SharedKey $pm.environment.get("azure_storage_account"):$signatureEncoded`);
然后保存并发送请求,您将得到如下输出:
预请求脚本参考:
Github
【讨论】:
【参考方案2】:Get Container ACL & Set Container ACL 目前只支持 SharedKey 认证。它们不支持 AAD 身份验证。
【讨论】:
以上是关于我面临使用 AAD 令牌作为身份验证的邮递员获取容器 ACL 和设置容器 ACL REST API 的问题的主要内容,如果未能解决你的问题,请参考以下文章
我是否可以使用AAD保护REST API(在春季启动时说)并从该AAD以用户身份访问它
azure 移动服务活动目录身份验证 X-ZUMO-AUTH 令牌在注销后在邮递员中有效