Lesson 35 - Get Compute Auth Token Working
This commit is contained in:
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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{}; };
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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 ®ion)
|
||||
: 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 ®ion)
|
||||
: 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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 ;
|
||||
};
|
||||
}
|
||||
@@ -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>();
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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 customer’s
|
||||
// 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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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() {};
|
||||
};
|
||||
}
|
||||
@@ -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 ®ion)
|
||||
: 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
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user