fix: AWS credential signing http request - convert form to body (#14060)

Co-authored-by: Dana <152518854+dana-gill@users.noreply.github.com>
This commit is contained in:
Mike Peachey
2025-04-17 11:30:04 +01:00
committed by GitHub
parent ddfe594cf0
commit 652d0f5428
2 changed files with 57 additions and 2 deletions

View File

@@ -476,13 +476,29 @@ export class Aws implements ICredentialType {
path = endpoint.pathname + endpoint.search;
// ! aws4.sign *must* have the body to sign, but we might have .form instead of .body
const requestWithForm = requestOptions as unknown as { form?: Record<string, string> };
let bodyContent = body !== '' ? body : undefined;
let contentTypeHeader: string | undefined = undefined;
if (requestWithForm.form) {
const params = new URLSearchParams();
for (const key in requestWithForm.form) {
params.append(key, requestWithForm.form[key]);
}
bodyContent = params.toString();
contentTypeHeader = 'application/x-www-form-urlencoded';
}
const signOpts = {
...requestOptions,
headers: requestOptions.headers ?? {},
headers: {
...(requestOptions.headers ?? {}),
...(contentTypeHeader && { 'content-type': contentTypeHeader }),
},
host: endpoint.host,
method,
path,
body: body !== '' ? body : undefined,
body: bodyContent,
region,
} as Request;

View File

@@ -139,5 +139,44 @@ describe('Aws Credential', () => {
expect(result.method).toBe('POST');
expect(result.url).toBe('https://iam.amazonaws.com/');
});
it('should handle an IRequestOptions object with form instead of body', async () => {
const result = await aws.authenticate({ ...credentials }, {
...requestOptions,
body: undefined,
form: {
Action: 'ListUsers',
Version: '2010-05-08',
},
baseURL: '',
url: 'https://iam.amazonaws.com',
host: 'iam.amazonaws.com',
path: '/',
} as IHttpRequestOptions);
expect(mockSign).toHaveBeenCalledWith(
{
...signOpts,
form: {
Action: 'ListUsers',
Version: '2010-05-08',
},
body: 'Action=ListUsers&Version=2010-05-08',
host: 'iam.amazonaws.com',
url: 'https://iam.amazonaws.com',
baseURL: '',
path: '/',
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
// PR #14037 introduces region normalization for global endpoints
// This test works with or without the normalization
region: expect.stringMatching(/[a-z]{2}-[a-z]+-[0-9]+/),
},
securityHeaders,
);
expect(result.method).toBe('POST');
expect(result.url).toBe('https://iam.amazonaws.com/');
});
});
});