@aws-sdk/middleware-signing
Version:
[](https://www.npmjs.com/package/@aws-sdk/middleware-signing) [](https://www.npmjs.com/packag
222 lines (214 loc) • 9.06 kB
JavaScript
;
var propertyProvider = require('@smithy/property-provider');
var signatureV4 = require('@smithy/signature-v4');
var utilMiddleware = require('@smithy/util-middleware');
var protocolHttp = require('@smithy/protocol-http');
const CREDENTIAL_EXPIRE_WINDOW = 300000;
const resolveAwsAuthConfig = (input) => {
const normalizedCreds = createConfigBoundCredentialProvider(input);
const { signingEscapePath = true, systemClockOffset = input.systemClockOffset || 0, sha256 } = input;
let signer;
if (input.signer) {
signer = utilMiddleware.normalizeProvider(input.signer);
}
else if (input.regionInfoProvider) {
signer = () => utilMiddleware.normalizeProvider(input.region)()
.then(async (region) => [
(await input.regionInfoProvider(region, {
useFipsEndpoint: await input.useFipsEndpoint(),
useDualstackEndpoint: await input.useDualstackEndpoint(),
})) || {},
region,
])
.then(([regionInfo, region]) => {
const { signingRegion, signingService } = regionInfo;
input.signingRegion = input.signingRegion || signingRegion || region;
input.signingName = input.signingName || signingService || input.serviceId;
const params = {
...input,
credentials: normalizedCreds,
region: input.signingRegion,
service: input.signingName,
sha256,
uriEscapePath: signingEscapePath,
};
const SignerCtor = input.signerConstructor || signatureV4.SignatureV4;
return new SignerCtor(params);
});
}
else {
signer = async (authScheme) => {
authScheme = Object.assign({}, {
name: "sigv4",
signingName: input.signingName || input.defaultSigningName,
signingRegion: await utilMiddleware.normalizeProvider(input.region)(),
properties: {},
}, authScheme);
const isSigv4a = authScheme?.name === "sigv4a";
const signingRegion = authScheme.signingRegion;
const signingService = authScheme.signingName;
let regionForSigner;
if (isSigv4a) {
regionForSigner = input.signingRegion || signingRegion;
}
else {
input.signingRegion = input.signingRegion || signingRegion;
regionForSigner = input.signingRegion;
}
input.signingName = input.signingName || signingService || input.serviceId;
const params = {
...input,
credentials: normalizedCreds,
region: regionForSigner,
service: input.signingName,
sha256,
uriEscapePath: signingEscapePath,
};
const SignerCtor = input.signerConstructor || signatureV4.SignatureV4;
return new SignerCtor(params);
};
}
return Object.assign(input, {
systemClockOffset,
signingEscapePath,
credentials: normalizedCreds,
signer,
});
};
const resolveSigV4AuthConfig = (input) => {
const normalizedCreds = createConfigBoundCredentialProvider(input);
const { signingEscapePath = true, systemClockOffset = input.systemClockOffset || 0, sha256 } = input;
let signer;
if (input.signer) {
signer = utilMiddleware.normalizeProvider(input.signer);
}
else {
signer = utilMiddleware.normalizeProvider(new signatureV4.SignatureV4({
credentials: normalizedCreds,
region: input.region,
service: input.signingName,
sha256,
uriEscapePath: signingEscapePath,
}));
}
return Object.assign(input, {
systemClockOffset,
signingEscapePath,
credentials: normalizedCreds,
signer,
});
};
const normalizeCredentialProvider = (credentials) => {
if (typeof credentials === "function") {
return propertyProvider.memoize(credentials, (credentials) => credentials.expiration !== undefined &&
credentials.expiration.getTime() - Date.now() < CREDENTIAL_EXPIRE_WINDOW, (credentials) => credentials.expiration !== undefined);
}
return utilMiddleware.normalizeProvider(credentials);
};
const createConfigBoundCredentialProvider = (input) => {
const normalizedCredentialsProvider = input.credentials
? normalizeCredentialProvider(input.credentials)
: input.credentialDefaultProvider(Object.assign({}, input, {
parentClientConfig: input,
}));
const normalizedCreds = async () => normalizedCredentialsProvider({
callerClientConfig: {
region: utilMiddleware.normalizeProvider(input.region),
profile: input.profile,
},
});
return normalizedCreds;
};
const getSkewCorrectedDate = (systemClockOffset) => new Date(Date.now() + systemClockOffset);
const isClockSkewed = (clockTime, systemClockOffset) => Math.abs(getSkewCorrectedDate(systemClockOffset).getTime() - clockTime) >= 300000;
const getUpdatedSystemClockOffset = (clockTime, currentSystemClockOffset) => {
const clockTimeInMs = Date.parse(clockTime);
if (isClockSkewed(clockTimeInMs, currentSystemClockOffset)) {
return clockTimeInMs - Date.now();
}
return currentSystemClockOffset;
};
const awsAuthMiddleware = (options) => (next, context) => async function (args) {
if (!protocolHttp.HttpRequest.isInstance(args.request))
return next(args);
let authScheme;
let signer;
const firstAuthScheme = context.endpointV2?.properties?.authSchemes?.[0];
const secondAuthScheme = context.endpointV2?.properties?.authSchemes?.[1];
const firstAuthSchemeIsSigv4a = firstAuthScheme?.name === "sigv4a";
if (firstAuthSchemeIsSigv4a && secondAuthScheme) {
signer = await options.signer((authScheme = firstAuthScheme));
const uncheckedSigner = signer;
const sigv4aAvailable = (() => {
if (typeof uncheckedSigner?.getSigv4aSigner === "function") {
if (uncheckedSigner?.signerOptions?.runtime !== "node") {
return false;
}
try {
uncheckedSigner.getSigv4aSigner();
return true;
}
catch (e) { }
}
return false;
})();
if (!sigv4aAvailable) {
signer = await options.signer((authScheme = secondAuthScheme));
}
}
else {
signer = await options.signer((authScheme = firstAuthScheme));
}
let signedRequest;
const multiRegionOverride = authScheme?.name === "sigv4a" ? authScheme?.signingRegionSet?.join(",") : undefined;
const signingOptions = {
signingDate: getSkewCorrectedDate(options.systemClockOffset),
signingRegion: multiRegionOverride || context["signing_region"],
signingService: context["signing_service"],
};
if (context.s3ExpressIdentity) {
const sigV4MultiRegion = signer;
signedRequest = await sigV4MultiRegion.signWithCredentials(args.request, context.s3ExpressIdentity, signingOptions);
if (signedRequest.headers["X-Amz-Security-Token"] || signedRequest.headers["x-amz-security-token"]) {
throw new Error("X-Amz-Security-Token must not be set for s3-express requests.");
}
}
else {
signedRequest = await signer.sign(args.request, signingOptions);
}
const output = await next({
...args,
request: signedRequest,
}).catch((error) => {
const serverTime = error.ServerTime ?? getDateHeader(error.$response);
if (serverTime) {
options.systemClockOffset = getUpdatedSystemClockOffset(serverTime, options.systemClockOffset);
}
throw error;
});
const dateHeader = getDateHeader(output.response);
if (dateHeader) {
options.systemClockOffset = getUpdatedSystemClockOffset(dateHeader, options.systemClockOffset);
}
return output;
};
const getDateHeader = (response) => protocolHttp.HttpResponse.isInstance(response) ? response.headers?.date ?? response.headers?.Date : undefined;
const awsAuthMiddlewareOptions = {
name: "awsAuthMiddleware",
tags: ["SIGNATURE", "AWSAUTH"],
relation: "after",
toMiddleware: "retryMiddleware",
override: true,
};
const getAwsAuthPlugin = (options) => ({
applyToStack: (clientStack) => {
clientStack.addRelativeTo(awsAuthMiddleware(options), awsAuthMiddlewareOptions);
},
});
const getSigV4AuthPlugin = getAwsAuthPlugin;
exports.awsAuthMiddleware = awsAuthMiddleware;
exports.awsAuthMiddlewareOptions = awsAuthMiddlewareOptions;
exports.getAwsAuthPlugin = getAwsAuthPlugin;
exports.getSigV4AuthPlugin = getSigV4AuthPlugin;
exports.resolveAwsAuthConfig = resolveAwsAuthConfig;
exports.resolveSigV4AuthConfig = resolveSigV4AuthConfig;