diff --git a/components/core/src/clp/aws/AwsAuthenticationSigner.cpp b/components/core/src/clp/aws/AwsAuthenticationSigner.cpp index 0b2d6fdb90..b058843b24 100644 --- a/components/core/src/clp/aws/AwsAuthenticationSigner.cpp +++ b/components/core/src/clp/aws/AwsAuthenticationSigner.cpp @@ -248,8 +248,8 @@ auto AwsAuthenticationSigner::get_canonical_query_string(string_view scope, string_view timestamp) const -> string { auto const uri = fmt::format("{}/{}", m_access_key_id, scope); - return fmt::format( - "{}={}&{}={}&{}={}&{}={}&{}={}", + auto canonical_query_string = fmt::format( + "{}={}&{}={}&{}={}&{}={}", cXAmzAlgorithm, cAws4HmacSha256, cXAmzCredential, @@ -257,10 +257,17 @@ AwsAuthenticationSigner::get_canonical_query_string(string_view scope, string_vi cXAmzDate, timestamp, cXAmzExpires, - cDefaultExpireTime.count(), - cXAmzSignedHeaders, - cDefaultSignedHeaders + cDefaultExpireTime.count() ); + if (m_session_token.has_value()) { + canonical_query_string.append(fmt::format( + "&{}={}", + cXAmzSecurityToken, + encode_uri(m_session_token.value(), false) + )); + } + canonical_query_string.append(fmt::format("&{}={}", cXAmzSignedHeaders, cDefaultSignedHeaders)); + return canonical_query_string; } auto AwsAuthenticationSigner::get_signing_key( diff --git a/components/core/src/clp/aws/AwsAuthenticationSigner.hpp b/components/core/src/clp/aws/AwsAuthenticationSigner.hpp index 293ffcd4cd..c665d6e46e 100644 --- a/components/core/src/clp/aws/AwsAuthenticationSigner.hpp +++ b/components/core/src/clp/aws/AwsAuthenticationSigner.hpp @@ -2,6 +2,7 @@ #define CLP_AWS_AWSAUTHENTICATIONSIGNER_HPP #include +#include #include #include #include @@ -69,9 +70,14 @@ class AwsAuthenticationSigner { static constexpr std::string_view cHttpGetMethod{"GET"}; // Constructors - AwsAuthenticationSigner(std::string access_key_id, std::string secret_access_key) + AwsAuthenticationSigner( + std::string access_key_id, + std::string secret_access_key, + std::optional session_token + ) : m_access_key_id{std::move(access_key_id)}, - m_secret_access_key{std::move(secret_access_key)} {} + m_secret_access_key{std::move(secret_access_key)}, + m_session_token{std::move(session_token)} {} // Methods /** @@ -129,6 +135,7 @@ class AwsAuthenticationSigner { // Variables std::string m_access_key_id; std::string m_secret_access_key; + std::optional m_session_token; }; } // namespace clp::aws diff --git a/components/core/src/clp/aws/constants.hpp b/components/core/src/clp/aws/constants.hpp index caebe92a1a..c85cfba531 100644 --- a/components/core/src/clp/aws/constants.hpp +++ b/components/core/src/clp/aws/constants.hpp @@ -12,6 +12,7 @@ constexpr std::string_view cXAmzAlgorithm{"X-Amz-Algorithm"}; constexpr std::string_view cXAmzCredential{"X-Amz-Credential"}; constexpr std::string_view cXAmzDate{"X-Amz-Date"}; constexpr std::string_view cXAmzExpires{"X-Amz-Expires"}; +constexpr std::string_view cXAmzSecurityToken{"X-Amz-Security-Token"}; constexpr std::string_view cXAmzSignature{"X-Amz-Signature"}; constexpr std::string_view cXAmzSignedHeaders{"X-Amz-SignedHeaders"}; diff --git a/components/core/src/clp_s/CommandLineArguments.cpp b/components/core/src/clp_s/CommandLineArguments.cpp index ece270a03e..7fcee9a705 100644 --- a/components/core/src/clp_s/CommandLineArguments.cpp +++ b/components/core/src/clp_s/CommandLineArguments.cpp @@ -274,7 +274,7 @@ CommandLineArguments::parse_arguments(int argc, char const** argv) { ->default_value(auth), "Type of authentication required for network requests (s3 | none). Authentication" " with s3 requires the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment" - " variables." + " variables, and optionally the AWS_SESSION_TOKEN environment variable." ); // clang-format on @@ -428,7 +428,7 @@ CommandLineArguments::parse_arguments(int argc, char const** argv) { ->default_value(auth), "Type of authentication required for network requests (s3 | none). Authentication" " with s3 requires the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment" - " variables." + " variables, and optionally the AWS_SESSION_TOKEN environment variable." ); // clang-format on extraction_options.add(decompression_options); @@ -582,7 +582,7 @@ CommandLineArguments::parse_arguments(int argc, char const** argv) { ->default_value(auth), "Type of authentication required for network requests (s3 | none). Authentication" " with s3 requires the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment" - " variables." + " variables, and optionally the AWS_SESSION_TOKEN environment variable." ); // clang-format on search_options.add(match_options); diff --git a/components/core/src/clp_s/InputConfig.hpp b/components/core/src/clp_s/InputConfig.hpp index 8c6afc2ea8..1d0eae35dd 100644 --- a/components/core/src/clp_s/InputConfig.hpp +++ b/components/core/src/clp_s/InputConfig.hpp @@ -11,6 +11,7 @@ namespace clp_s { // Constants used for input configuration constexpr char cAwsAccessKeyIdEnvVar[] = "AWS_ACCESS_KEY_ID"; constexpr char cAwsSecretAccessKeyEnvVar[] = "AWS_SECRET_ACCESS_KEY"; +constexpr char cAwsSessionTokenEnvVar[] = "AWS_SESSION_TOKEN"; /** * Enum class defining the source of a resource. diff --git a/components/core/src/clp_s/ReaderUtils.cpp b/components/core/src/clp_s/ReaderUtils.cpp index 6286d367fc..b0f3e31820 100644 --- a/components/core/src/clp_s/ReaderUtils.cpp +++ b/components/core/src/clp_s/ReaderUtils.cpp @@ -1,6 +1,7 @@ #include "ReaderUtils.hpp" #include +#include #include #include @@ -164,8 +165,17 @@ bool try_sign_url(std::string& url) { ); return false; } + std::optional optional_aws_session_token{std::nullopt}; + auto const aws_session_token = std::getenv(cAwsSessionTokenEnvVar); + if (nullptr != aws_session_token) { + optional_aws_session_token = std::string{aws_session_token}; + } - clp::aws::AwsAuthenticationSigner signer{aws_access_key, aws_secret_access_key}; + clp::aws::AwsAuthenticationSigner signer{ + aws_access_key, + aws_secret_access_key, + optional_aws_session_token + }; try { clp::aws::S3Url s3_url{url};