我尝试使用来自aws合成金丝雀的lambda url调用lambda函数,当我在邮递员中提供我的秘密和访问密钥时,它可以工作,但不能从aws合成金丝雀我遵循aws官方文档提供lambda:InvokeFunctionUrl政策,但仍然出现禁止错误
我发现下面是我的合成金丝雀 lambda,我正在其中创建 aws 签名来签署 http 请求。 任何有问题的人只需更改 accessKey、secretKey 和 URL
const crypto = require('crypto');
const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const syntheticsConfiguration = synthetics.getConfiguration();
const apiCanaryBlueprint = async function () {
syntheticsConfiguration.setConfig({
restrictedHeaders: [],
restrictedUrlParameters: []
});
// AWS credentials from environment variables
const accessKeyId = "${accessKeyId}";
const secretAccessKey = "${secretAccessKey}";
const endpointUrl = "${endpoint_url}";
// Helper function to create AWS Signature Version 4 headers
function signRequest(requestOptions, region, service) {
const endpoint = new URL('https://' + requestOptions.hostname + requestOptions.path);
const method = requestOptions.method || 'GET';
const now = new Date();
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
const dateStamp = amzDate.slice(0, 8);
// Canonical request
const canonicalUri = endpoint.pathname;
const canonicalQuerystring = '';
const canonicalHeaders = 'host:' + endpoint.hostname + '\n' + 'x-amz-date:' + amzDate + '\n';
const signedHeaders = 'host;x-amz-date';
const payloadHash = crypto.createHash('sha256').update(requestOptions.body || '', 'utf8').digest('hex');
const canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\n' + signedHeaders + '\n' + payloadHash;
// String to sign
const algorithm = 'AWS4-HMAC-SHA256';
const credentialScope = dateStamp + '/' + region + '/' + service + '/aws4_request';
const stringToSign = algorithm + '\n' + amzDate + '\n' + credentialScope + '\n' + crypto.createHash('sha256').update(canonicalRequest, 'utf8').digest('hex');
// Calculate the signature
const signingKey = getSignatureKey(secretAccessKey, dateStamp, region, service);
const signature = crypto.createHmac('sha256', signingKey).update(stringToSign, 'utf8').digest('hex');
// Add headers to request options
requestOptions.headers['x-amz-date'] = amzDate;
requestOptions.headers['Authorization'] = algorithm + ' Credential=' + accessKeyId + '/' + credentialScope + ', SignedHeaders=' + signedHeaders + ', Signature=' + signature;
}
// Helper function to derive the signing key
function getSignatureKey(key, dateStamp, regionName, serviceName) {
const kDate = crypto.createHmac('sha256', 'AWS4' + key).update(dateStamp).digest();
const kRegion = crypto.createHmac('sha256', kDate).update(regionName).digest();
const kService = crypto.createHmac('sha256', kRegion).update(serviceName).digest();
const kSigning = crypto.createHmac('sha256', kService).update('aws4_request').digest();
return kSigning;
}
const validateSuccessful = async function (res) {
return new Promise((resolve, reject) => {
if (res.statusCode < 200 || res.statusCode > 299) {
throw new Error(res.statusCode + ' ' + res.statusMessage);
}
let responseBody = '';
res.on('data', (d) => {
responseBody += d;
});
res.on('end', () => {
resolve();
});
});
}
function extractRequestOptions(endpointUrl) {
// Parse the URL using the URL constructor
const parsedUrl = new URL(endpointUrl);
// Create an object similar to requestOptionsStep1
const requestOptions = {
hostname: parsedUrl.hostname,
method: "POST",
path: parsedUrl.pathname,
port: parsedUrl.port || '443',
protocol: parsedUrl.protocol,
body: "",
headers: {}
};
return requestOptions;
}
// Set request option for Verify
let requestOptionsStep1 = extractRequestOptions(endpointUrl);
// Sign the request manually
signRequest(requestOptionsStep1, 'ca-central-1', 'lambda');
// Add the User-Agent header
requestOptionsStep1['headers']['User-Agent'] = [synthetics.getCanaryUserAgentString(), requestOptionsStep1['headers']['User-Agent']].join(' ');
let stepConfig1 = {
includeRequestHeaders: false,
includeResponseHeaders: false,
includeRequestBody: false,
includeResponseBody: false,
continueOnHttpStepFailure: true
};
await synthetics.ex