使用 IAM 授权从 EC2 访问 AWS API Gateway (NodeJS)

2024-02-05

也许我要走一座桥到很远的地方,但这就是我得到的:

  • 为授权设置了 AWS_IAM 的 AWS API Gateway 方法。
  • 允许访问该方法的策略。
  • 附加了该策略的 EC2 角色。
  • 具有该角色的 EC2 已启动。

我希望 EC2 上的 NodeJS 程序(或任何与此相关的语言)能够调用该 API,而无需在代码中硬编码 AccessKey 和 SecretKey。

我已经使用这种方法使用 aws-sdk 在 S3 上放置/获取记录,并执行其他 AWS 功能(如我上面提到的所有步骤),但是,调用 API 网关似乎超出了 aws-sdk 范围。

使用 Wreck(我在应用程序中的 HTTP 调用中使用的 NPM)调用 API 并且没有标头会导致:

{
  "message": "Missing Authentication Token"
}

那里并没有什么大的震惊。

我缺少什么明显的东西吗?


所以看来您需要访问您的 EC2http://169.254.169.254/latest/meta-data/iam/security-credentials/Role_Name

正如所解释的here http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html.

这是我的最终代码,包括使用签名版本 4 签署 AWS 请求 http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html:

var Moment = require('moment');
var Wreck = require('wreck');
var Crypto = require('crypto');

function getSignatureKey(key, dateStamp, regionName, serviceName) {
    var kDate = Crypto.createHmac('sha256', 'AWS4' + key).update(dateStamp,'utf8').digest();
    var kRegion = Crypto.createHmac('sha256', kDate).update(regionName, 'utf8').digest();
    var kService = Crypto.createHmac('sha256', kRegion).update(serviceName, 'utf8').digest();
    var kSigning = Crypto.createHmac('sha256', kService).update('aws4_request', 'utf8').digest();
    return kSigning;
}

var assumed_role = 'MY_ROLE';
Wreck.get('http://169.254.169.254/latest/meta-data/iam/security-credentials/' + assumed_role, function(err, res, payload) {
    var payload_obj = JSON.parse(payload.toString());
    var access_key = payload_obj.AccessKeyId;
    var secret_key = payload_obj.SecretAccessKey;
    var token = payload_obj.Token;

    var payload = {}
    payload.email = '[email protected] /cdn-cgi/l/email-protection';
    payload.first_name = 'Devin';
    payload.last_name = 'Stewart';
    payload.full_name = 'Devin Stewart';

    var request_parameters = JSON.stringify(payload);

    var method = 'POST';
    var api_id = 'MY_API_ID'
    var service = 'execute-api';
    var region = 'us-east-1';
    var api_path = '/production/people';
    var host = api_id + '.' + service + '.' + region + '.amazonaws.com';
    var endpoint = 'https://' + host + api_path;
    var content_type = 'application/json';

    var t = Moment.utc()
    var amz_date = t.format('YYYYMMDD[T]HHmmss[Z]');
    var date_stamp = t.format('YYYYMMDD'); // Date w/o time, used in credential scope

    var canonical_querystring = '';
    var canonical_headers = 'content-type:' + content_type + '\n' + 'host:' + host + '\n' + 'x-amz-date:' + amz_date + '\n' + 'x-amz-security-token:' + token + '\n';
    var signed_headers = 'content-type;host;x-amz-date;x-amz-security-token';
    var payload_hash = Crypto.createHash('sha256').update(request_parameters).digest('hex');
    var canonical_request = method + '\n' + api_path + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash;

    var algorithm = 'AWS4-HMAC-SHA256';
    var credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request';
    var string_to_sign = algorithm + '\n' +  amz_date + '\n' +  credential_scope + '\n' +  Crypto.createHash('sha256').update(canonical_request).digest('hex');

    var signing_key = getSignatureKey(secret_key, date_stamp, region, service);
    var signature = Crypto.createHmac('sha256', signing_key).update(string_to_sign, 'utf8').digest('hex');

    authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature;
    var headers = { 
        'Content-Type':content_type,
        'X-Amz-Date':amz_date,
        'X-Amz-Security-Token':token,
        'Authorization':authorization_header
    };

    var options = {headers: headers, payload: request_parameters};
    Wreck.post(endpoint, options, function (err, res, payload) {
        if (err) {
            console.log(err.data.payload.toString());
        } else {
            console.log(payload.toString());
        }
    });
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 IAM 授权从 EC2 访问 AWS API Gateway (NodeJS) 的相关文章

  • AWS Lambda 调用错误未触发 SQS 死信队列

    我有一个 AWS Lambda 函数 它订阅 DynamoDB 流并配置了SQS 死信队列 DLQ https docs aws amazon com lambda latest dg dlq html 我可以看到管理控制台中配置了正确的队
  • 如何通过id获取最近共享的AWS RDS快照?

    我在 AWS RDS 上有 2 个数据库 其中一个用于stage和一个用于production跨 2 个帐户 我正在尝试将数据复制到production to stage每 x 天 我的计划是复制最近的自动备份快照production并分享
  • Rails 的 Puma Systemd 配置不起作用

    我已经完成了一个使用 Ruby on Rails 构建的应用程序 现在我想将其托管在 AWS 上的 EC2 实例上 我已经为其配置了服务器 并且正在使用pumaHTTP服务器作为应用服务器 在生产中启动应用程序总是需要我运行RAILS EN
  • 如何将 kubernetes LoadBalancer Ingress URL 发布到 aws Route53

    今天 当我通过 aws 使用 kubernetes 启动一个应用程序时 它公开了一个公开可见的 LoadBalancer Ingress URL 但是要将其链接到我的域以使公众可以访问该应用程序 我需要在每个设备上的浏览器中手动进入 aws
  • AWS Textract InvalidParameterException

    我有一个 Net core 客户端应用程序 根据 AWS 文档 使用带有 S3 SNS 和 SQS 的 amazon Textract 检测和分析多页文档中的文本 https docs aws amazon com texttract la
  • AWS LoadBalancer监听多个端口

    我有一些应用程序在 aws 中作为微服务运行 其中一些在端口 80 上运行 一些在端口 3000 上运行 我希望我的 ALB 侦听这两个端口上的流量 然后我有一个ListenRules将流量引导至微服务 我想实现如下所示的目标 Resour
  • AWS Cognito - 如何确定用户是否使用电子邮件或电话号码注册

    我们已经按照描述实施了自定义身份验证触发器here https docs aws amazon com cognito latest developerguide user pool lambda challenge html 我们设置了用
  • 使用 AWS API Gateway 和 Lambda 从 multipart/form-data 获取非文件正文

    我正在尝试从multipart form data POST通过 API 网关连接到我的 AWS Lambda Web 服务 超文本传输 协议POST具有内容类型 multipart form data 和 URL 编码的正文 文件数据也在
  • 如何更改 Amazon Redshift 中的默认时区?

    默认情况下将时间戳列设置为 SYSDATE 将其存储为UTC 是否可以更改时区 以便 SYSDATE 将日期和时间存储到不同的时区 到目前为止 我已经检查了SET http docs aws amazon com redshift late
  • Amazon Web Services:设置 S3 策略以允许 putObject 和 getObject 但拒绝 listBucket

    我在 Amazon S3 上使用 getObject 和 putObject 请求 并在创建访问存储桶的策略时发现 如果我不允许 listBucket 则会收到 访问被拒绝 错误 这样做的问题是 listBucket 意味着用户可以列出存储
  • 解锁 Jenkins - 如何

    我已经使用 putty 从 Windows 系统在我的 ec2 实例上安装了 jenkins 当我尝试通过网络访问 jenkins 时 我使用 var lib jenkins secrets initialAdminPassword 解锁
  • 亚马逊 AWS CloudFront 声称不存在这样的存储桶

    我正在尝试设置 CloudFront 来提供图像 但当前无法访问它并返回错误 指定的存储桶不存在
  • 在 Elastic Beanstalk SSH 上运行 Django 命令 -> 缺少环境变量

    所以这对我来说是一个长期存在的问题 我很想解决它 我也认为这会帮助很多其他人 我希望在 Elastic Beanstalk EC2 实例上进行 ssh 操作后运行 Django 命令 例如 python manage py dumpdata
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • 如何增加vm.max_map_count?

    我正在尝试在 Ubuntu EC2 计算机 t2 medium 中运行弹性搜索 但我收到消息 最大虚拟内存区域 vm max map count 65530 太低 至少增加到 262144 我怎样才能增加vm max map count v
  • 带有 AWS S3 文件的 Icecast 服务器

    我目前正在运行 Icecast 服务器 用于在 EC2 实例上传输音频 目前我所有的 mp3 文件都存储在 EC2 实例上 我想将它们移动到 AWS S3 进行存储 到目前为止 我已经能够找到能够更新播放列表 https mediareal
  • 在 ec2 上托管 Rails

    我想将 Rails 部署到亚马逊 ec2 上 我看过 poolparty 和 ec2onrails 但似乎都不再维护了 人们用什么来做到这一点 都是自制的木偶和卡皮斯特拉诺 还是有一个项目可以让我继续下去 我可以推荐两个项目 如果您有一个
  • AWS Amazon - 登录循环卡住

    我已经使用 AWS 亚马逊几年了 但是 突然当我登录时 我进入了此验证部分 他们将验证码发送到我的电子邮件 我收到了该代码 因此 我输入收到的代码 最终返回登录页面 所以我登录后 同样的事情一遍又一遍地发生 我无法进入我的仪表板 它只是不断
  • 如何在PHP中将图像从内存上传到AWS S3?

    所以我目前有一个使用 AWS S3 上传图像的上传系统 这是代码 Upload image to S3 s3 Aws S3 S3Client factory array key gt mykey secret gt myskey try s
  • 无法使用 aws 无服务器离线从另一个 lambda 调用 lambda

    我想从 serverless offline 内的另一个 lambda 调用 lambda 我想创建一个无服务器离线 Web 应用程序 但我收到此错误 UnknownError 不支持的媒体类型 在 Object extractError

随机推荐