diff --git a/packages/middleware-signing/src/awsAuthConfiguration.ts b/packages/middleware-signing/src/awsAuthConfiguration.ts index f9d0ab4b977cd..8fc40e1400906 100644 --- a/packages/middleware-signing/src/awsAuthConfiguration.ts +++ b/packages/middleware-signing/src/awsAuthConfiguration.ts @@ -194,11 +194,22 @@ export const resolveAwsAuthConfig = ( authScheme ); + const isSigv4a = authScheme?.name === "sigv4a"; + const signingRegion = authScheme.signingRegion; const signingService = authScheme.signingName; - // update client's singing region and signing service config if they are resolved. - // signing region resolving order: user supplied signingRegion -> endpoints.json inferred region -> client region - input.signingRegion = input.signingRegion || signingRegion; + + let regionForSigner: string | undefined; + + if (isSigv4a) { + regionForSigner = input.signingRegion || signingRegion; + } else { + // update client's signing region and signing service config if they are resolved. + // signing region resolving order: user supplied signingRegion -> endpoints.json inferred region -> client region + input.signingRegion = input.signingRegion || signingRegion; + regionForSigner = input.signingRegion; + } + // signing name resolving order: // user supplied signingName -> endpoints.json inferred (credential scope -> model arnNamespace) -> model service id input.signingName = input.signingName || signingService || input.serviceId; @@ -206,7 +217,7 @@ export const resolveAwsAuthConfig = ( const params: SignatureV4Init & SignatureV4CryptoInit = { ...input, credentials: normalizedCreds, - region: input.signingRegion, + region: regionForSigner, service: input.signingName, sha256, uriEscapePath: signingEscapePath, diff --git a/packages/middleware-signing/src/awsAuthMiddleware.ts b/packages/middleware-signing/src/awsAuthMiddleware.ts index 0a31fb0f6b7e0..b738c3610830e 100644 --- a/packages/middleware-signing/src/awsAuthMiddleware.ts +++ b/packages/middleware-signing/src/awsAuthMiddleware.ts @@ -10,6 +10,7 @@ import { HttpRequest as IHttpRequest, Pluggable, RelativeMiddlewareOptions, + RequestSigner, } from "@smithy/types"; import { AwsAuthResolvedConfig } from "./awsAuthConfiguration"; @@ -25,14 +26,40 @@ export const awsAuthMiddleware = if (!HttpRequest.isInstance(args.request)) return next(args); // TODO(identityandauth): call authScheme resolver - const authScheme: AuthScheme | undefined = context.endpointV2?.properties?.authSchemes?.[0]; + let authScheme: AuthScheme | undefined; + let signer: RequestSigner | undefined; + + 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 as any; + const sigv4aAvailable = (() => { + if (typeof uncheckedSigner?.getSigv4aSigner === "function") { + if (uncheckedSigner?.signerOptions?.runtime !== "node") { + return false; + } + try { + uncheckedSigner.getSigv4aSigner(); + return true; + } catch (e: unknown) {} + } + return false; + })(); + if (!sigv4aAvailable) { + signer = await options.signer((authScheme = secondAuthScheme)); + } + } else { + signer = await options.signer((authScheme = firstAuthScheme)); + } + + let signedRequest: IHttpRequest; const multiRegionOverride: string | undefined = authScheme?.name === "sigv4a" ? authScheme?.signingRegionSet?.join(",") : undefined; - const signer = await options.signer(authScheme); - - let signedRequest: IHttpRequest; const signingOptions = { signingDate: getSkewCorrectedDate(options.systemClockOffset), signingRegion: multiRegionOverride || context["signing_region"],