Skip to content

feat(core): resolve auth schemes based on the preference list #1571

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

trivikr
Copy link
Contributor

@trivikr trivikr commented Apr 24, 2025

Issue #, if available:
Internal JS-5811

Description of changes:
Resolves auth schemes based on the preference list

Testing is done by installing @aws-sdk/client-s3 and @smithy/core, and validating signature

$ yarn add ../aws-sdk-js-v3/clients/client-s3/aws-sdk-client-s3-3.796.0.tgz
$ yarn add ../smithy-typescript/packages/core/smithy-core-3.2.0.tgz
$ cp -R node_modules/@smithy/core/* node_modules/@aws-sdk/client-s3/node_modules/@smithy/core

Test code

import { S3 } from "@aws-sdk/client-s3";
import "@aws-sdk/signature-v4-crt";

const interceptorMiddleware = (next, context) => (args) => {
  // middleware intercept the request and return it early
  const request = args.request;
  return Promise.resolve({
    output: {
      $metadata: { attempts: 0, httpStatusCode: 200 },
      request,
      context,
    },
    response: {},
  });
};

const OutpostId = "op-01234567890123456";
const AccountId = "123456789012";
const region = "us-west-2";
const clientRegion = "us-east-1";
const credentials = { accessKeyId: "key", secretAccessKey: "secret" };

const client = new S3({
  region: clientRegion,
  credentials,
  useArnRegion: true,
  authSchemePreference: ["sigv4"],
});

client.middlewareStack.add(interceptorMiddleware, {
  step: "finalizeRequest",
  priority: "low",
});

const result = await client.putObject({
  Bucket: `arn:aws:s3-outposts:${region}:${AccountId}:outpost/${OutpostId}/accesspoint/abc-111`,
  Key: "key",
  Body: "body",
});

const headers = result.request.headers;
const authorizationHeader =
  headers["authorization"] || headers["Authorization"];

// Prints "AWS4-ECDSA-P256-SHA256" when authSchemePreference starts with "sigv4a", or is not set.
// Prints "AWS4-HMAC-SHA256" when authSchemePreference is set to "sigv4".
console.log(authorizationHeader.split(" ")[0]);

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@trivikr trivikr changed the title Resolve auth schemes based on the preference list feat(core): resolve auth schemes based on the preference list Apr 24, 2025
@trivikr

This comment was marked as outdated.

@trivikr trivikr marked this pull request as ready for review April 25, 2025 07:03
@trivikr trivikr requested a review from a team as a code owner April 25, 2025 07:03
}
}

return preferredAuthOptions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the lists are so small, I feel that this is optional, but you can do this without nested for loops like this:

// runnable in console
{
const candidates = [{ id: 'a', }, { id: 'b' }];
const preference = ['c', 'b'];

const candidateMap = candidates.reduce((map, item) => {
  map.set(item.id, item);
  return map;
}, new Map);

const preferredMap = new Map;

for (const pref of preference) {
  if (candidateMap.has(pref)) {
    preferredMap.set(pref, candidateMap.get(pref));
  }
}

for (const [id, item] of candidateMap) {
  preferredMap.set(id, item);
}

console.log([...preferredMap.values()])
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should retain the resolve function, as it's recommended in the internal cross SDK proposal.
Also, the JS SDK implementation uses map for authSchemes which do not have order preserved. The order is preserved in authOptions instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if you're referring to the Map in the example, but those retain insertion order like modern objects.

But let's keep the function as is since it is in the design.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants