Lesson 35 - Get Compute Auth Token Working

This commit is contained in:
Norman Lansing
2026-02-28 12:32:28 -05:00
parent 1d477ee42a
commit 4fde462bce
7743 changed files with 1397833 additions and 18 deletions

View File

@@ -0,0 +1,31 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/resolver/AwsIdentityResolverBase.h>
#include <smithy/identity/signer/AwsSignerBase.h>
namespace smithy {
template<typename IDENTITY_T>
class AuthScheme
{
public:
using IdentityT = IDENTITY_T;
template<std::size_t N>
AuthScheme(char const (&iSchemeId)[N])
{
memcpy(schemeId, iSchemeId, N);
}
char schemeId[32];
virtual ~AuthScheme() = default;
virtual std::shared_ptr<IdentityResolverBase<IdentityT>> identityResolver() = 0;
virtual std::shared_ptr<AwsSignerBase<IdentityT>> signer() = 0;
};
}

View File

@@ -0,0 +1,30 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <aws/crt/Variant.h>
#include <aws/core/utils/DateTime.h>
#include <aws/core/utils/memory/stl/AWSMap.h>
#include <aws/core/endpoint/EndpointParameter.h>
namespace smithy {
/* AuthSchemeOption and AuthSchemeOptionResolver */
class AuthSchemeOption
{
using PropertyBag = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>;
using EndpointParameters = Aws::Vector<Aws::Endpoint::EndpointParameter>;
/* note: AuthSchemeOption is not connected with AuthScheme by type system, only by the String of schemeId, this is in accordance with SRA */
public:
AuthSchemeOption(const char* id = nullptr): schemeId(id) {}
virtual ~AuthSchemeOption() = default;
const char* schemeId = nullptr;
PropertyBag virtual identityProperties() const { return PropertyBag{}; };
PropertyBag virtual signerProperties() const { return PropertyBag{}; };
EndpointParameters virtual endpointParameters() const { return EndpointParameters{}; };
};
}

View File

@@ -0,0 +1,42 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthSchemeOption.h>
#include <smithy/identity/signer/AwsSignerBase.h>
#include <aws/crt/Variant.h>
#include <aws/core/utils/memory/stl/AWSMap.h>
namespace smithy {
/**
* A base interface for code-generated interfaces for passing in the data required for determining the
* authentication scheme. By default, this only includes the operation name.
*/
class DefaultAuthSchemeResolverParameters
{
public:
Aws::String serviceName;
Aws::String operation;
Aws::Crt::Optional<Aws::String> region;
Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String,
bool,
Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy,
Aws::Auth::AWSSigningAlgorithm > > additionalProperties;
};
template<typename ServiceAuthSchemeParametersT = DefaultAuthSchemeResolverParameters>
class AuthSchemeResolverBase
{
public:
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
virtual ~AuthSchemeResolverBase() = default;
// AuthScheme Resolver returns a list of AuthSchemeOptions for some reason, according to the SRA...
virtual Aws::Vector<AuthSchemeOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) = 0;
};
}

View File

@@ -0,0 +1,59 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthScheme.h>
#include <smithy/identity/auth/built-in/BearerTokenAuthSchemeOption.h>
#include <smithy/identity/identity/AwsBearerTokenIdentityBase.h>
#include <smithy/identity/resolver/AwsBearerTokenIdentityResolver.h>
#include <smithy/identity/signer/built-in/BearerTokenSigner.h>
namespace smithy
{
class BearerTokenAuthScheme : public AuthScheme<AwsBearerTokenIdentityBase>
{
public:
using AwsCredentialIdentityResolverT = IdentityResolverBase<IdentityT>;
using AwsCredentialSignerT = AwsSignerBase<IdentityT>;
using BearerTokenAuthSchemeParameters = DefaultAuthSchemeResolverParameters;
// This allows to override the identity resolver
explicit BearerTokenAuthScheme(
std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver,
const Aws::String &serviceName, const Aws::String &region)
: AuthScheme("smithy.api#HTTPBearerAuth"),
m_identityResolver{identityResolver},
m_signer{Aws::MakeShared<smithy::BearerTokenSigner>(
"BearerTokenAuthScheme", serviceName, region)}
{
assert(m_identityResolver);
assert(m_signer);
}
explicit BearerTokenAuthScheme(const Aws::String &serviceName,
const Aws::String &region)
: BearerTokenAuthScheme(
Aws::MakeShared<DefaultAwsBearerTokenIdentityResolver>(
"BearerTokenAuthScheme"),
serviceName, region)
{
assert(m_identityResolver);
assert(m_signer);
}
virtual ~BearerTokenAuthScheme() = default;
std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver() override
{
return m_identityResolver;
}
std::shared_ptr<AwsCredentialSignerT> signer() override { return m_signer; }
protected:
std::shared_ptr<AwsCredentialIdentityResolverT> m_identityResolver;
std::shared_ptr<AwsCredentialSignerT> m_signer;
};
} // namespace smithy

View File

@@ -0,0 +1,17 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthSchemeOption.h>
namespace smithy
{
struct BearerTokenAuthSchemeOption
{
static AuthSchemeOption bearerTokenAuthSchemeOption;
};
AuthSchemeOption BearerTokenAuthSchemeOption::bearerTokenAuthSchemeOption =
AuthSchemeOption("smithy.api#HTTPBearerAuth");
} // namespace smithy

View File

@@ -0,0 +1,28 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthSchemeResolverBase.h>
#include <smithy/identity/auth/built-in/BearerTokenAuthSchemeOption.h>
namespace smithy
{
template <typename ServiceAuthSchemeParametersT =
DefaultAuthSchemeResolverParameters>
class BearerTokenAuthSchemeResolver
: public AuthSchemeResolverBase<ServiceAuthSchemeParametersT>
{
public:
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
virtual ~BearerTokenAuthSchemeResolver() = default;
Aws::Vector<AuthSchemeOption> resolveAuthScheme(
const ServiceAuthSchemeParameters &identityProperties) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
return {BearerTokenAuthSchemeOption::bearerTokenAuthSchemeOption};
}
};
} // namespace smithy

View File

@@ -0,0 +1,63 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthScheme.h>
#include <smithy/identity/auth/built-in/SigV4AuthSchemeOption.h>
#include <smithy/identity/resolver/built-in/DefaultAwsCredentialIdentityResolver.h>
#include <smithy/identity/identity/AwsCredentialIdentityBase.h>
#include <smithy/identity/signer/built-in/SigV4Signer.h>
#include <smithy/identity/auth/built-in/SigV4AuthScheme.h>
namespace smithy {
constexpr char SIGV4[] = "aws.auth#sigv4";
class SigV4AuthScheme : public AuthScheme<AwsCredentialIdentityBase>
{
public:
using AwsCredentialIdentityResolverT = IdentityResolverBase<IdentityT>;
using AwsCredentialSignerT = AwsSignerBase<IdentityT>;
using SigV4AuthSchemeParameters = DefaultAuthSchemeResolverParameters;
//This allows to override the identity resolver
explicit SigV4AuthScheme(std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver,
const Aws::String& serviceName,
const Aws::String& region)
: AuthScheme(SIGV4),
m_identityResolver{identityResolver},
m_signer{Aws::MakeShared<AwsSigV4Signer>("SigV4AuthScheme", serviceName, region)}
{
assert(m_identityResolver);
assert(m_signer);
}
//delegate constructor
explicit SigV4AuthScheme(const Aws::String& serviceName,
const Aws::String& region)
: SigV4AuthScheme(Aws::MakeShared<DefaultAwsCredentialIdentityResolver>("SigV4AuthScheme"),
serviceName,
region)
{
}
virtual ~SigV4AuthScheme() = default;
std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver() override
{
return m_identityResolver;
}
std::shared_ptr<AwsCredentialSignerT> signer() override
{
return m_signer;
}
protected:
std::shared_ptr<AwsCredentialIdentityResolverT> m_identityResolver;
std::shared_ptr<AwsCredentialSignerT> m_signer;
};
}

View File

@@ -0,0 +1,15 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/Smithy_EXPORTS.h>
#include <smithy/identity/auth/AuthSchemeOption.h>
namespace smithy {
struct SigV4AuthSchemeOption
{
static SMITHY_API AuthSchemeOption sigV4AuthSchemeOption;
};
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthSchemeResolverBase.h>
#include <smithy/identity/auth/built-in/SigV4AuthSchemeOption.h>
namespace smithy {
template<typename ServiceAuthSchemeParametersT = DefaultAuthSchemeResolverParameters>
class SigV4AuthSchemeResolver : public AuthSchemeResolverBase<ServiceAuthSchemeParametersT>
{
public:
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
virtual ~SigV4AuthSchemeResolver() = default;
Aws::Vector<AuthSchemeOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
return {SigV4AuthSchemeOption::sigV4AuthSchemeOption};
}
};
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthScheme.h>
#include <smithy/identity/auth/built-in/SigV4aAuthSchemeOption.h>
#include <smithy/identity/resolver/built-in/DefaultAwsCredentialIdentityResolver.h>
#include <smithy/identity/identity/AwsCredentialIdentityBase.h>
#include <smithy/identity/signer/built-in/SigV4aSigner.h>
namespace smithy {
constexpr char SIGV4A[] = "aws.auth#sigv4a";
class SigV4aAuthScheme : public AuthScheme<AwsCredentialIdentityBase>
{
public:
using AwsCredentialIdentityResolverT = IdentityResolverBase<IdentityT>;
using AwsCredentialSignerT = AwsSignerBase<IdentityT>;
using SigV4aAuthSchemeParameters = DefaultAuthSchemeResolverParameters;
//This allows to override the identity resolver
explicit SigV4aAuthScheme(std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver,
const Aws::String& serviceName,
const Aws::String& region)
: AuthScheme(SIGV4A),
m_identityResolver{identityResolver},
m_signer{Aws::MakeShared<AwsSigV4aSigner>("SigV4aAuthScheme", serviceName, region)}
{
assert(m_identityResolver);
assert(m_signer);
}
explicit SigV4aAuthScheme(const Aws::String& serviceName,
const Aws::String& region)
: SigV4aAuthScheme(Aws::MakeShared<DefaultAwsCredentialIdentityResolver>("SigV4aAuthScheme"), serviceName, region)
{
assert(m_identityResolver);
assert(m_signer);
}
virtual ~SigV4aAuthScheme() = default;
std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver() override
{
return m_identityResolver;
}
std::shared_ptr<AwsCredentialSignerT> signer() override
{
return m_signer;
}
protected:
std::shared_ptr<AwsCredentialIdentityResolverT> m_identityResolver;
std::shared_ptr<AwsCredentialSignerT> m_signer;
};
}

View File

@@ -0,0 +1,15 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/Smithy_EXPORTS.h>
#include <smithy/identity/auth/AuthSchemeOption.h>
namespace smithy {
struct SigV4aAuthSchemeOption
{
static SMITHY_API AuthSchemeOption sigV4aAuthSchemeOption;
};
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/auth/AuthSchemeResolverBase.h>
#include <smithy/identity/auth/built-in/SigV4aAuthSchemeOption.h>
namespace smithy {
template<typename ServiceAuthSchemeParametersT = DefaultAuthSchemeResolverParameters>
class SigV4aAuthSchemeResolver : public AuthSchemeResolverBase<ServiceAuthSchemeParametersT>
{
public:
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
virtual ~SigV4aAuthSchemeResolver() = default;
Aws::Vector<AuthSchemeOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
return {SigV4aAuthSchemeOption::sigV4aAuthSchemeOption};
}
};
}

View File

@@ -0,0 +1,30 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsBearerTokenIdentityBase.h>
namespace smithy {
class AwsBearerTokenIdentity : public AwsBearerTokenIdentityBase {
public:
virtual const Aws::String &token() const override;
virtual Aws::Crt::Optional<AwsIdentity::DateTime>
expiration() const override;
Aws::String &token() { return m_token; }
Aws::Crt::Optional<AwsIdentity::DateTime> &expiration()
{
return m_expiration;
}
protected:
Aws::String m_token;
Aws::Crt::Optional<AwsIdentity::DateTime> m_expiration;
};
}
#include <smithy/identity/identity/impl/AwsBearerTokenIdentityImpl.h>

View File

@@ -0,0 +1,17 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsIdentity.h>
namespace smithy {
class AwsBearerTokenIdentityBase : public AwsIdentity {
public:
virtual const Aws::String &token() const = 0;
virtual Aws::Crt::Optional<AwsIdentity::DateTime>
expiration() const override = 0;
};
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsCredentialIdentityBase.h>
namespace smithy {
class AwsCredentialIdentity : public AwsCredentialIdentityBase {
public:
AwsCredentialIdentity(const Aws::String& accessKeyId,
const Aws::String& secretAccessKey,
const Aws::Crt::Optional<Aws::String>& sessionToken,
const Aws::Crt::Optional<AwsIdentity::DateTime>& expiration)
: m_accessKeyId(accessKeyId), m_secretAccessKey(secretAccessKey),
m_sessionToken(sessionToken), m_expiration(expiration) {}
Aws::String accessKeyId() const override;
Aws::String secretAccessKey() const override;
Aws::Crt::Optional<Aws::String> sessionToken() const override;
Aws::Crt::Optional<AwsIdentity::DateTime> expiration() const override;
protected:
Aws::String m_accessKeyId;
Aws::String m_secretAccessKey;
Aws::Crt::Optional<Aws::String> m_sessionToken;
Aws::Crt::Optional<AwsIdentity::DateTime> m_expiration;
};
}
#include <smithy/identity/identity/impl/AwsCredentialIdentityImpl.h>

View File

@@ -0,0 +1,17 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsIdentity.h>
namespace smithy {
class AwsCredentialIdentityBase : public AwsIdentity {
public:
virtual Aws::String accessKeyId() const = 0;
virtual Aws::String secretAccessKey() const = 0;
virtual Aws::Crt::Optional<Aws::String> sessionToken() const = 0;
virtual Aws::Crt::Optional<AwsIdentity::DateTime> expiration() const override = 0 ;
};
}

View File

@@ -0,0 +1,21 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <aws/crt/Optional.h>
#include <aws/core/utils/DateTime.h>
namespace smithy {
class AwsIdentity {
public:
using DateTime = Aws::Utils::DateTime;
virtual ~AwsIdentity(){};
virtual Aws::Crt::Optional<DateTime> expiration() const {
return Aws::Crt::Optional<DateTime>();
};
};
}

View File

@@ -0,0 +1,18 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsBearerTokenIdentity.h>
namespace smithy {
const Aws::String &AwsBearerTokenIdentity::token() const { return m_token; }
Aws::Crt::Optional<AwsIdentity::DateTime>
AwsBearerTokenIdentity::expiration() const
{
return m_expiration;
}
}

View File

@@ -0,0 +1,26 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsCredentialIdentity.h>
namespace smithy {
inline Aws::String AwsCredentialIdentity::accessKeyId() const {
return m_accessKeyId;
}
inline Aws::String AwsCredentialIdentity::secretAccessKey() const {
return m_secretAccessKey;
}
inline Aws::Crt::Optional<Aws::String> AwsCredentialIdentity::sessionToken() const {
return m_sessionToken;
}
inline Aws::Crt::Optional<AwsIdentity::DateTime> AwsCredentialIdentity::expiration() const {
return m_expiration;
}
}

View File

@@ -0,0 +1,97 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h>
#include <aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h>
#include <smithy/identity/identity/AwsBearerTokenIdentity.h>
#include <smithy/identity/resolver/AwsIdentityResolverBase.h>
namespace smithy
{
class AwsBearerTokenIdentityResolver
: public IdentityResolverBase<AwsBearerTokenIdentityBase>
{
public:
static const char BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG[];
using IdentityT = AwsBearerTokenIdentity;
virtual ~AwsBearerTokenIdentityResolver() = default;
AwsBearerTokenIdentityResolver() = default;
AwsBearerTokenIdentityResolver(
const Aws::Vector<
std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase>>
&providerChain)
: m_providerChainLegacy{providerChain}
{
}
ResolveIdentityFutureOutcome
getIdentity(const IdentityProperties &identityProperties,
const AdditionalParameters &additionalParameters) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
AWS_UNREFERENCED_PARAM(additionalParameters);
for (auto &bearerTokenProvider : m_providerChainLegacy)
{
if (!bearerTokenProvider)
{
AWS_LOGSTREAM_FATAL(
BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG,
"Unexpected nullptr in "
"DefaultBearerTokenProviderChain::m_providerChain");
return Aws::Client::AWSError<Aws::Client::CoreErrors>(
Aws::Client::CoreErrors::INVALID_PARAMETER_VALUE, "",
"Unexpected nullptr in "
"BearerTokenProviderChain::m_providerChain",
false);
}
auto bearerToken = bearerTokenProvider->GetAWSBearerToken();
if (!bearerToken.IsExpiredOrEmpty())
{
auto outcomePtr = Aws::MakeUnique<AwsBearerTokenIdentity>(
BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG);
outcomePtr->token() = bearerToken.GetToken();
outcomePtr->expiration() = bearerToken.GetExpiration();
return ResolveIdentityFutureOutcome(std::move(outcomePtr));
}
}
return Aws::Client::AWSError<Aws::Client::CoreErrors>(
Aws::Client::CoreErrors::NOT_INITIALIZED, "",
"No bearer token provider in chain found", false);
}
void AddBearerTokenProvider(
std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase> provider)
{
m_providerChainLegacy.emplace_back(std::move(provider));
}
protected:
Aws::Vector<std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase>>
m_providerChainLegacy;
};
class DefaultAwsBearerTokenIdentityResolver
: public AwsBearerTokenIdentityResolver
{
public:
using IdentityT = AwsBearerTokenIdentity;
virtual ~DefaultAwsBearerTokenIdentityResolver() = default;
DefaultAwsBearerTokenIdentityResolver()
: AwsBearerTokenIdentityResolver(
{Aws::MakeShared<Aws::Auth::SSOBearerTokenProvider>(
"SSOBearerTokenProvider")}){};
};
const char
AwsBearerTokenIdentityResolver::BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG[] =
"BearerTokenProvider";
} // namespace smithy

View File

@@ -0,0 +1,19 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/resolver/AwsIdentityResolverBase.h>
#include <smithy/identity/identity/AwsCredentialIdentity.h>
namespace smithy {
class AwsCredentialIdentityResolver : public IdentityResolverBase<AwsCredentialIdentityBase> {
public:
using IdentityT = AwsCredentialIdentity;
virtual ~AwsCredentialIdentityResolver() = default;
ResolveIdentityFutureOutcome getIdentity(const IdentityProperties& identityProperties, const AdditionalParameters& additionalParameters) override = 0;
};
}

View File

@@ -0,0 +1,36 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <aws/crt/Optional.h>
#include <aws/crt/Variant.h>
#include <aws/core/client/CoreErrors.h>
#include <aws/core/utils/FutureOutcome.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSMap.h>
#include <aws/core/utils/DateTime.h>
namespace smithy {
template<typename IDENTITY_T>
class IdentityResolverBase {
public:
using IdentityT = IDENTITY_T;
virtual ~IdentityResolverBase(){};
using IdentityProperties = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>;
// IdentityResolvers are asynchronous.
using ResolveIdentityFutureOutcome = Aws::Utils::FutureOutcome<Aws::UniquePtr<IdentityT>, Aws::Client::AWSError<Aws::Client::CoreErrors>>;
using AdditionalParameters = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>;
// Each Identity has one or more identity resolvers that are able to load the customers
// Identity. An identity resolver might load the identity from a remote service (e.g. STS), a local
// service (e.g. IMDS), local disk (e.g. a configuration file) or local memory (e.g. environment variables).
virtual ResolveIdentityFutureOutcome getIdentity(const IdentityProperties& identityProperties, const AdditionalParameters& additionalParameters) = 0;
};
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/resolver/AwsCredentialIdentityResolver.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>
namespace smithy
{
class AwsCredentialsProviderIdentityResolver : public AwsCredentialIdentityResolver
{
public:
using SigV4AuthSchemeParameters = DefaultAuthSchemeResolverParameters;
explicit AwsCredentialsProviderIdentityResolver(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> credentialsProvider)
: m_credentialsProvider(credentialsProvider)
{
}
AwsCredentialsProviderIdentityResolver(const AwsCredentialsProviderIdentityResolver& other) = delete;
AwsCredentialsProviderIdentityResolver(AwsCredentialsProviderIdentityResolver&& other) noexcept = default;
AwsCredentialsProviderIdentityResolver& operator=(const AwsCredentialsProviderIdentityResolver& other) = delete;
AwsCredentialsProviderIdentityResolver& operator=(AwsCredentialsProviderIdentityResolver&& other) noexcept = default;
~AwsCredentialsProviderIdentityResolver() override = default;
ResolveIdentityFutureOutcome getIdentity(const IdentityProperties& identityProperties,
const AdditionalParameters& additionalParameters) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
AWS_UNREFERENCED_PARAM(additionalParameters);
const auto fetchedCreds = m_credentialsProvider->GetAWSCredentials();
auto smithyCreds = Aws::MakeUnique<AwsCredentialIdentity>("DefaultAwsCredentialIdentityResolver",
fetchedCreds.GetAWSAccessKeyId(), fetchedCreds.GetAWSSecretKey(),
fetchedCreds.GetSessionToken(), fetchedCreds.GetExpiration());
return {std::move(smithyCreds)};
}
protected:
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> m_credentialsProvider;
};
}

View File

@@ -0,0 +1,57 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/resolver/AwsCredentialIdentityResolver.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>
namespace smithy {
constexpr char ALLOC_ID[] = "DefaultAwsCredentialIdentityResolver";
/**
* A smithy SigV4 AWS Credentials resolver wrapper on top of legacy SDK Credentials provider
* TODO: refactor into own signer using smithy design
*/
class DefaultAwsCredentialIdentityResolver : public AwsCredentialIdentityResolver {
protected:
mutable std::shared_ptr<Aws::Auth::AWSCredentialsProviderChain> legacyChain_sp;
public:
using SigV4AuthSchemeParameters = DefaultAuthSchemeResolverParameters;
DefaultAwsCredentialIdentityResolver(): legacyChain_sp{Aws::MakeShared<Aws::Auth::DefaultAWSCredentialsProviderChain>(ALLOC_ID)}{
};
DefaultAwsCredentialIdentityResolver(const DefaultAwsCredentialIdentityResolver& other) = delete;
DefaultAwsCredentialIdentityResolver(DefaultAwsCredentialIdentityResolver&& other) noexcept = default;
DefaultAwsCredentialIdentityResolver& operator=(const DefaultAwsCredentialIdentityResolver& other) = delete;
DefaultAwsCredentialIdentityResolver& operator=(DefaultAwsCredentialIdentityResolver&& other) noexcept = default;
virtual ~DefaultAwsCredentialIdentityResolver() = default;
DefaultAwsCredentialIdentityResolver(std::shared_ptr<Aws::Auth::AWSCredentialsProviderChain> providerChain): legacyChain_sp{providerChain}
{
assert(legacyChain_sp);
};
ResolveIdentityFutureOutcome getIdentity(const IdentityProperties& identityProperties, const AdditionalParameters& additionalParameters) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
AWS_UNREFERENCED_PARAM(additionalParameters);
auto legacyCreds = legacyChain_sp->GetAWSCredentials();
auto smithyCreds = Aws::MakeUnique<AwsCredentialIdentity>("DefaultAwsCredentialIdentityResolver",
legacyCreds.GetAWSAccessKeyId(),
legacyCreds.GetAWSSecretKey(),
legacyCreds.GetSessionToken().empty()? Aws::Crt::Optional<Aws::String>() : legacyCreds.GetSessionToken(),
legacyCreds.GetExpiration());
return ResolveIdentityFutureOutcome(std::move(smithyCreds));
}
};
}

View File

@@ -0,0 +1,46 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/resolver/AwsCredentialIdentityResolver.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>
namespace smithy
{
class SimpleAwsCredentialIdentityResolver : public AwsCredentialIdentityResolver
{
public:
using SigV4AuthSchemeParameters = DefaultAuthSchemeResolverParameters;
explicit SimpleAwsCredentialIdentityResolver(const Aws::Auth::AWSCredentials& credentials)
: m_credentials(credentials)
{
}
SimpleAwsCredentialIdentityResolver(const SimpleAwsCredentialIdentityResolver& other) = delete;
SimpleAwsCredentialIdentityResolver(SimpleAwsCredentialIdentityResolver&& other) noexcept = default;
SimpleAwsCredentialIdentityResolver& operator=(const SimpleAwsCredentialIdentityResolver& other) = delete;
SimpleAwsCredentialIdentityResolver& operator=(SimpleAwsCredentialIdentityResolver&& other) noexcept = default;
virtual ~SimpleAwsCredentialIdentityResolver() = default;
ResolveIdentityFutureOutcome getIdentity(const IdentityProperties& identityProperties,
const AdditionalParameters& additionalParameters) override
{
AWS_UNREFERENCED_PARAM(identityProperties);
AWS_UNREFERENCED_PARAM(additionalParameters);
auto smithyCreds = Aws::MakeUnique<AwsCredentialIdentity>("DefaultAwsCredentialIdentityResolver",
m_credentials.GetAWSAccessKeyId(), m_credentials.GetAWSSecretKey(),
m_credentials.GetSessionToken(), m_credentials.GetExpiration());
return {std::move(smithyCreds)};
}
protected:
Aws::Auth::AWSCredentials m_credentials;
};
}

View File

@@ -0,0 +1,52 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <atomic>
#include <smithy/identity/identity/AwsIdentity.h>
#include <aws/crt/Variant.h>
#include <aws/core/client/AWSError.h>
#include <aws/core/http/HttpRequest.h>
#include <aws/core/utils/FutureOutcome.h>
#include <aws/core/utils/memory/stl/AWSMap.h>
namespace smithy {
class AwsSignerCommon {
public:
virtual ~AwsSignerCommon() = default;
/**
* This handles detection of clock skew between clients and the server and adjusts the clock so that the next request will not
* fail on the timestamp check.
*/
virtual void SetClockSkew(const std::chrono::milliseconds& clockSkew) { m_clockSkew = clockSkew; }
/**
* Gets the timestamp being used by the signer. This may include a clock skew if a clock skew has been detected.
*/
virtual Aws::Utils::DateTime GetSigningTimestamp() const { return Aws::Utils::DateTime::Now() + GetClockSkewOffset(); }
protected:
virtual std::chrono::milliseconds GetClockSkewOffset() const { return m_clockSkew.load(); }
std::atomic<std::chrono::milliseconds> m_clockSkew = {};
};
template<typename IDENTITY_T>
class AwsSignerBase : public AwsSignerCommon {
public:
using IdentityT = IDENTITY_T;
static_assert(std::is_base_of<AwsIdentity, IDENTITY_T>::value, "Identity type should inherit AwsIdentity");
using SigningProperties = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>;
using AdditionalParameters = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>;
using HttpRequest = Aws::Http::HttpRequest;
using SigningError = Aws::Client::AWSError<Aws::Client::CoreErrors>;
using SigningFutureOutcome = Aws::Utils::FutureOutcome<std::shared_ptr<HttpRequest>, SigningError>;
// signer may copy the original httpRequest or create a new one
virtual SigningFutureOutcome sign(std::shared_ptr<HttpRequest> httpRequest, const IdentityT& identity, SigningProperties properties) = 0;
virtual ~AwsSignerBase() {};
};
}

View File

@@ -0,0 +1,68 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/identity/AwsBearerTokenIdentityBase.h>
#include <smithy/identity/signer/AwsSignerBase.h>
#include <aws/core/auth/signer/AWSAuthSignerHelper.h>
#include <aws/core/http/HttpRequest.h>
#include <aws/crt/http/HttpConnection.h>
#include <aws/crt/http/HttpRequestResponse.h>
namespace smithy
{
static const char AUTHORIZATION_HEADER[] = "authorization";
class BearerTokenSigner : public AwsSignerBase<AwsBearerTokenIdentityBase>
{
public:
static const char LOGGING_TAG[];
using BearerTokenAuthSchemeParameters =
smithy::DefaultAuthSchemeResolverParameters;
explicit BearerTokenSigner(const Aws::String &serviceName,
const Aws::String &region)
: m_serviceName(serviceName), m_region(region)
{
}
SigningFutureOutcome
sign(std::shared_ptr<HttpRequest> httpRequest,
const smithy::AwsBearerTokenIdentityBase &identity,
SigningProperties properties) override
{
AWS_UNREFERENCED_PARAM(properties);
if (Aws::Http::Scheme::HTTPS != httpRequest->GetUri().GetScheme())
{
// Clients MUST always use TLS (https) or equivalent transport
// security when making requests with bearer tokens.
// https://datatracker.ietf.org/doc/html/rfc6750
AWS_LOGSTREAM_ERROR(
LOGGING_TAG,
"HTTPS scheme must be used with a bearer token authorization");
return SigningError(
Aws::Client::CoreErrors::INVALID_PARAMETER_VALUE, "",
"Failed to sign the request with bearer", false);
}
httpRequest->SetHeaderValue(AUTHORIZATION_HEADER,
"Bearer " + identity.token());
return SigningFutureOutcome(std::move(httpRequest));
}
virtual ~BearerTokenSigner(){};
protected:
Aws::String m_serviceName;
Aws::String m_region;
};
const char BearerTokenSigner::LOGGING_TAG[] = "BearerTokenSigner";
} // namespace smithy

View File

@@ -0,0 +1,64 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/signer/AwsSignerBase.h>
#include <smithy/identity/identity/AwsCredentialIdentityBase.h>
#include <aws/core/auth/signer/AWSAuthV4Signer.h>
#include <aws/core/auth/AWSCredentials.h>
namespace smithy {
/**
* A smithy SigV4 signer wrapper on top of legacy SDK SigV4 signer
* TODO: refactor into own signer using smithy design
*/
class AwsSigV4Signer : public AwsSignerBase<AwsCredentialIdentityBase> {
public:
using SigV4AuthSchemeParameters = DefaultAuthSchemeResolverParameters;
explicit AwsSigV4Signer(const Aws::String& serviceName, const Aws::String& region)
: m_serviceName(serviceName),
m_region(region),
legacySigner(nullptr, serviceName.c_str(), region, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Always)
{
}
SigningFutureOutcome sign(std::shared_ptr<HttpRequest> httpRequest, const AwsCredentialIdentityBase& identity, SigningProperties properties) override
{
const auto legacyCreds = [&identity]() -> Aws::Auth::AWSCredentials {
if(identity.sessionToken().has_value() && identity.expiration().has_value())
{
return {identity.accessKeyId(), identity.secretAccessKey(), *identity.sessionToken(), *identity.expiration()};
}
if(identity.sessionToken().has_value())
{
return {identity.accessKeyId(), identity.secretAccessKey(), *identity.sessionToken()};
}
return {identity.accessKeyId(), identity.secretAccessKey()};
}();
auto signPayloadIt = properties.find("SignPayload");
bool signPayload = signPayloadIt != properties.end() ? signPayloadIt->second.get<Aws::String>() == "true" : false;
assert(httpRequest);
bool success = legacySigner.SignRequestWithCreds(*httpRequest, legacyCreds, m_region.c_str(), m_serviceName.c_str(), signPayload);
if (success)
{
return SigningFutureOutcome(std::move(httpRequest));
}
return SigningError(Aws::Client::CoreErrors::MEMORY_ALLOCATION, "", "Failed to sign the request with sigv4", false);
}
virtual ~AwsSigV4Signer() {};
protected:
Aws::String m_serviceName;
Aws::String m_region;
Aws::Client::AWSAuthV4Signer legacySigner;
};
}

View File

@@ -0,0 +1,219 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <smithy/identity/signer/AwsSignerBase.h>
#include <smithy/identity/identity/AwsCredentialIdentityBase.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/crt/auth/Credentials.h>
#include <aws/core/http/HttpRequest.h>
#include <aws/core/auth/signer/AWSAuthSignerHelper.h>
#include <aws/crt/http/HttpConnection.h>
#include <aws/crt/http/HttpRequestResponse.h>
#include <condition_variable>
#include <mutex>
namespace smithy {
static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
static const char v4AsymmetricLogTag[] = "AWSAuthSymmetricV4Signer";
static const char* USER_AGENT = "user-agent";
static const char* X_AMZN_TRACE_ID = "x-amzn-trace-id";
/**
* A smithy SigV4 signer wrapper on top of legacy SDK SigV4 signer
* TODO: refactor into own signer using smithy design
*/
class AwsSigV4aSigner : public AwsSignerBase<AwsCredentialIdentityBase> {
public:
using SigV4aAuthSchemeParameters = smithy::DefaultAuthSchemeResolverParameters;
explicit AwsSigV4aSigner(const Aws::String& serviceName, const Aws::String& region)
: m_serviceName(serviceName), m_region(region)
{
}
SigningFutureOutcome sign(std::shared_ptr<HttpRequest> httpRequest, const AwsCredentialIdentityBase& identity, SigningProperties properties) override
{
auto signPayloadIt = properties.find("SignPayload");
bool signPayload = signPayloadIt != properties.end() ? signPayloadIt->second.get<Aws::String>() == "true" : false;
assert(httpRequest);
assert(identity.expiration().has_value());
auto &request = *httpRequest;
auto crtCredentials = Aws::MakeShared<Aws::Crt::Auth::Credentials>(v4AsymmetricLogTag,
Aws::Crt::ByteCursorFromCString(identity.accessKeyId().c_str()),
Aws::Crt::ByteCursorFromCString(identity.secretAccessKey().c_str()),
Aws::Crt::ByteCursorFromCString((*identity.sessionToken()).c_str()),
(*identity.expiration()).Seconds());
Aws::Crt::Auth::AwsSigningConfig awsSigningConfig;
bool success = createAwsSigningConfig(crtCredentials, request, awsSigningConfig, signPayload);
if(!success)
{
AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "Failed to get Auth configuration");
return SigningError(Aws::Client::CoreErrors::MEMORY_ALLOCATION, "", "Failed to get Auth configuration", false);
}
std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest = request.ToCrtHttpRequest();
auto sigv4HttpRequestSigner = Aws::MakeShared<Aws::Crt::Auth::Sigv4HttpRequestSigner>(v4AsymmetricLogTag);
//This is an async call, so we need to wait till we have received an outcome
Aws::String errorMessage;
bool processed = false;
//producer function
sigv4HttpRequestSigner->SignRequest(crtHttpRequest, awsSigningConfig,
[&request, &success, &errorMessage, &processed, this](const std::shared_ptr<Aws::Crt::Http::HttpRequest>& signedCrtHttpRequest, int errorCode) {
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [&]{ return !processed; });
success = (errorCode == AWS_ERROR_SUCCESS);
if (success)
{
if (m_signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders)
{
for (size_t i = 0; i < signedCrtHttpRequest->GetHeaderCount(); i++)
{
Aws::Crt::Optional<Aws::Crt::Http::HttpHeader> httpHeader = signedCrtHttpRequest->GetHeader(i);
request.SetHeaderValue(Aws::String(reinterpret_cast<const char*>(httpHeader->name.ptr), httpHeader->name.len),
Aws::String(reinterpret_cast<const char*>(httpHeader->value.ptr), httpHeader->value.len));
}
}
else if (m_signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams)
{
Aws::Http::URI newPath(reinterpret_cast<const char*>(signedCrtHttpRequest->GetPath()->ptr));
request.GetUri().SetQueryString(newPath.GetQueryString());
}
else
{
errorMessage = "No action to take when signature type is neither \"HttpRequestViaHeaders\" nor \"HttpRequestViaQueryParams\"";
AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, errorMessage);
success = false;
}
}
else
{
Aws::OStringStream errStream;
errStream << "Encountered internal error during signing process with AWS signature version 4 (Asymmetric):" << aws_error_str(errorCode);
errorMessage = errStream.str();
AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, errorMessage);
}
processed = true;
m_cv.notify_all();
}
);
//consumer
{
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [&]{ return processed; });
}
return success? SigningFutureOutcome(std::move(httpRequest)) : SigningError(Aws::Client::CoreErrors::MEMORY_ALLOCATION, "", "Failed to sign the request with sigv4", false);
}
virtual ~AwsSigV4aSigner() {};
protected:
bool createAwsSigningConfig(
std::shared_ptr<Aws::Crt::Auth::Credentials>& crtCredentials,
const Aws::Http::HttpRequest& request,
Aws::Crt::Auth::AwsSigningConfig& awsSigningConfig,
bool signBody) const
{
awsSigningConfig.SetSigningAlgorithm(static_cast<Aws::Crt::Auth::SigningAlgorithm>(Aws::Auth::AWSSigningAlgorithm::ASYMMETRIC_SIGV4));
awsSigningConfig.SetSignatureType(m_signatureType);
awsSigningConfig.SetRegion(m_region.c_str());
awsSigningConfig.SetService(m_region.c_str());
awsSigningConfig.SetSigningTimepoint(GetSigningTimestamp().UnderlyingTimestamp());
awsSigningConfig.SetUseDoubleUriEncode(m_urlEscape);
awsSigningConfig.SetShouldNormalizeUriPath(true);
awsSigningConfig.SetOmitSessionToken(false);
awsSigningConfig.SetShouldSignHeaderUserData(reinterpret_cast<void*>(const_cast<Aws::Set<Aws::String>*>(&m_unsignedHeaders)));
awsSigningConfig.SetShouldSignHeaderCallback([](const Aws::Crt::ByteCursor *name, void *user_data) {
Aws::Set<Aws::String>* unsignedHeaders = static_cast<Aws::Set<Aws::String>*>(user_data);
Aws::String headerKey(reinterpret_cast<const char*>(name->ptr), name->len);
return unsignedHeaders->find(Aws::Utils::StringUtils::ToLower(headerKey.c_str())) == unsignedHeaders->cend();
});
if (m_signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders)
{
Aws::String payloadHash(UNSIGNED_PAYLOAD);
if(signBody || request.GetUri().GetScheme() != Aws::Http::Scheme::HTTPS)
{
if (!request.GetContentBody())
{
AWS_LOGSTREAM_DEBUG(v4AsymmetricLogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty.");
payloadHash = EMPTY_STRING_SHA256;
}
else
{
// The hash will be calculated from the payload during signing.
payloadHash = {};
}
}
else
{
AWS_LOGSTREAM_DEBUG(v4AsymmetricLogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody
<< " http scheme=" << Aws::Http::SchemeMapper::ToString(request.GetUri().GetScheme()));
}
awsSigningConfig.SetSignedBodyValue(payloadHash.c_str());
awsSigningConfig.SetSignedBodyHeader(m_includeSha256HashHeader ? Aws::Crt::Auth::SignedBodyHeaderType::XAmzContentSha256 : Aws::Crt::Auth::SignedBodyHeaderType::None);
}
else if (m_signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams)
{
if (ServiceRequireUnsignedPayload(m_serviceName))
{
awsSigningConfig.SetSignedBodyValue(UNSIGNED_PAYLOAD);
}
else
{
awsSigningConfig.SetSignedBodyValue(EMPTY_STRING_SHA256);
}
}
else
{
AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "The signature type should be either \"HttpRequestViaHeaders\" or \"HttpRequestViaQueryParams\"");
return false;
}
awsSigningConfig.SetExpirationInSeconds(static_cast<uint64_t>(m_expirationTimeInSeconds));
awsSigningConfig.SetCredentials(crtCredentials);
return true;
}
bool ServiceRequireUnsignedPayload(const Aws::String& serviceName) const
{
// S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here:
// https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
// this is true for PUT, POST, GET, DELETE and HEAD operations.
// However, other services (for example RDS) implement the specification as outlined here:
// https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
// which states that body-less requests should use the empty-string SHA256 hash.
return "s3" == serviceName || "s3-object-lambda" == serviceName;
}
Aws::String m_serviceName;
Aws::String m_region;
//params that can be exposed later
long long m_expirationTimeInSeconds{0};
const bool m_includeSha256HashHeader{true};
const bool m_urlEscape{true};
const Aws::Set<Aws::String> m_unsignedHeaders{USER_AGENT,X_AMZN_TRACE_ID};
const Aws::Crt::Auth::SignatureType m_signatureType{Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams};
std::condition_variable m_cv;
std::mutex m_mutex;
};
}