You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Logic App调用ACS REST API发送SMS遇HTTP 401未授权错误求助

问题排查与修复方案

你的401未授权错误,核心原因是HMAC签名生成的细节不符合ACS的要求,以下是逐一排查和修复步骤:

1. Authorization头缺失必填参数

ACS的HMAC-SHA256授权头必须包含SharedAccessKeyName,对应你ACS资源的访问策略名称(比如默认的root,或者你自定义的策略名)。你当前的代码完全没加这个参数,导致ACS无法识别签名对应的权限策略,直接拒绝请求。

修复代码:
修改授权头生成逻辑,添加SharedAccessKeyName:

// 替换为你ACS资源的访问策略名称,比如默认的"root"
const sharedAccessKeyName = "root";
const authorizationHeader = `HMAC-SHA256 SignedHeaders=date;host;x-ms-content-sha256&SharedAccessKeyName=${sharedAccessKeyName}&Signature=${signature}`;

2. 请求体哈希不一致

你在Function里用JSON.stringify(requestBody)生成请求体的SHA256哈希,但Logic App发给ACS的请求体必须和这个序列化结果完全一模一样(包括空格、键的顺序、引号格式)。如果Logic App的Compose输出或后续传递中自动调整了JSON格式,哈希就会不匹配,签名直接失效。

验证与修复:

  • 在Function的返回体里加个requestBodyJson: JSON.stringify(requestBody),同时在Logic App里抓一下调用ACS前的请求体,对比两者是否完全相同。
  • 如果不一致,要么在Logic App里用string()函数把Compose输出转成字符串直接传,要么让Function直接返回序列化后的请求体字符串,供Logic App调用ACS时用。

3. Date头必须严格同步

ACS要求签名里的date值和请求的Date头完全一致,而且请求时间和服务器时间差不能超过15分钟。如果Logic App拿到Function返回的Date头后延迟太久才调用ACS,或者中途改了Date值,签名就会失效。

验证与修复:

  • Logic App调用ACS时,直接用Function返回的Date头值,别做任何修改。
  • 检查Function生成的dateStr格式是不是标准UTC格式(比如Wed, 10 Jul 2024 12:34:56 GMT),别搞出格式错误。

4. URL路径签名范围确认

ACS签名规则里,stringToSign的URL部分只需要绝对路径(不含主机和查询参数),你当前代码里的url = "/sms"是对的(api-version属于查询参数,不用包含在签名里),这部分不用改,但要确保Logic App调用ACS的URL确实是/sms,查询参数api-version=2021-03-07没错。

5. Host头正确性

确认Logic App调用ACS时的Host头和Function里的hostStr完全一致(就是acs-myendpointname.europe.communication.azure.com,别带:443端口)。如果Logic App自动加了端口,手动把Host头改成正确的值。

完整修复后的Function代码

const CryptoJS = require('crypto-js');
module.exports = async function (context, req) {
  const dateStr = new Date().toUTCString();
  let requestBody = req.body;
  // 序列化请求体,确保和Logic App发给ACS的完全一致
  const requestBodyJson = JSON.stringify(requestBody);
  const hashedBodyStr = CryptoJS.SHA256(requestBodyJson).toString(CryptoJS.enc.Base64);
  const endpoint = 'https://acs-myendpointname.europe.communication.azure.com';
  const hostStr = endpoint.replace('https://', '');
  const url = `/sms`;
  const stringToSign = `${req.method}\n${url}\n${dateStr};${hostStr};${hashedBodyStr}`;
  // 替换为你的ACS访问密钥
  const key = CryptoJS.enc.Base64.parse('6LdYArmyververysecretaccesskeyAAAAAZCSUpsh');
  // 替换为你的ACS访问策略名称
  const sharedAccessKeyName = "root";
  const signature = CryptoJS.HmacSHA256(stringToSign, key).toString(CryptoJS.enc.Base64);
  const authorizationHeader = `HMAC-SHA256 SignedHeaders=date;host;x-ms-content-sha256&SharedAccessKeyName=${sharedAccessKeyName}&Signature=${signature}`;
  
  context.res = {
      headers: {
          'Date': dateStr,
          'x-ms-content-sha256': hashedBodyStr,
          'Authorization': authorizationHeader
      },
      body: {
          message: 'Headers set successfully',
          signedString: stringToSign,
          signature: signature,
          requestBodyJson: requestBodyJson // 用于验证请求体一致性
      }
  };
};

额外验证步骤

  1. Logic App里直接用Function返回的requestBodyJson作为请求体发给ACS,避免格式差异。
  2. 把Postman里的请求体、Date、Host等参数代入Function逻辑,看生成的签名和Postman的是否一致,验证代码逻辑是否正确。

内容的提问来源于stack exchange,提问作者joostvdlinden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 05:22:13