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

使用AWS4-HMAC-SHA256签名请求时遇SignatureDoesNotMatch错误排查

解决AWS STS AssumeRole请求的SignatureDoesNotMatch错误

问题根源

你的代码对aws4.sign的path参数设置错误——你把包含协议和域名的完整URL传给了path,但AWS签名计算规则里,path应该仅包含域名之后的部分(即从/?开始的路径与查询字符串)。这种不匹配导致签名计算的请求内容和实际发送的请求内容不一致,最终触发签名验证失败。

修复步骤

  1. 拆分URL结构:将完整的请求地址拆分为host(域名部分)和path(路径+查询参数部分),避免把协议和域名混入path。
  2. 修正签名参数:确保aws4.sign的path参数只传入拆分后的路径部分,和实际请求的路径保持完全一致。
  3. 保持请求URL正确:fetch请求仍使用完整的endpoint,但签名逻辑必须基于正确的拆分参数。

修正后的代码

import * as aws4 from 'aws4'

async getStsCredentials() {
    
  const awsCredentials = {
    accessKeyId: 'xxx',
    secretAccessKey: 'xxx',
    region: 'us-east-1', 
  };
  
  const params = {
    RoleArn: 'xxx', 
    RoleSessionName: 'test', 
    DurationSeconds: 3600, 
  };
  
  // 拆分host和path,避免将完整URL传入签名的path参数
  const host = `sts.${awsCredentials.region}.amazonaws.com`;
  const path = `/?Version=2011-06-15&Action=AssumeRole&RoleSessionName=${params.RoleSessionName}&RoleArn=${encodeURIComponent(params.RoleArn)}&DurationSeconds=${params.DurationSeconds}`;
  const endpoint = `https://${host}${path}`;
  
  const signedRequest = aws4.sign(
    {
      service: 'sts',
      region: awsCredentials.region,
      method: 'GET',
      host: host,
      path: path, // 这里仅传入路径+查询参数,而非完整URL
    },
    awsCredentials
  );
  
  // 发送请求
  fetch(endpoint, {
    headers:{
      'Authorization': signedRequest.headers.Authorization as string,
      'x-amz-date': signedRequest.headers['X-Amz-Date'] as string
    }
  })
      .then((response) => response.text())
      .then((result) => console.log(result))
      .catch((error) => console.log('error', error));
}

额外注意事项

  • 确认RoleArn已用encodeURIComponent正确编码特殊字符,避免查询参数解析异常。
  • HTTP请求头大小写不敏感,但建议保持x-amz-date与签名生成的X-Amz-Date一致,减少潜在的兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:00:10