Skip to content

Commit fbc2f92

Browse files
Smithy Identity AuthOption and AuthScheme
1 parent 30d6642 commit fbc2f92

File tree

6 files changed

+275
-0
lines changed

6 files changed

+275
-0
lines changed

src/aws-cpp-sdk-core/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ file(GLOB UTILS_STREAM_HEADERS "include/aws/core/utils/stream/*.h")
7373
file(GLOB CJSON_HEADERS "include/aws/core/external/cjson/*.h")
7474
file(GLOB TINYXML2_HEADERS "include/aws/core/external/tinyxml2/tinyxml2.h")
7575
file(GLOB SMITHY_HEADERS "include/smithy/*.h")
76+
file(GLOB SMITHY_CLIENT_HEADERS "include/smithy/client/*.h" "include/smithy/client/impl/*.h")
7677
file(GLOB SMITHY_TRACING_HEADERS "include/smithy/tracing/*.h")
7778
file(GLOB SMITHY_IDENTITY_HEADERS "include/smithy/identity/*.h")
79+
file(GLOB SMITHY_IDENTITY_AUTH_HEADERS "include/smithy/identity/auth/*.h" "include/smithy/identity/auth/impl/*.h")
7880
file(GLOB SMITHY_IDENTITY_IDENTITY_HEADERS "include/smithy/identity/identity/*.h" "include/smithy/identity/identity/impl/*.h")
7981
file(GLOB SMITHY_IDENTITY_RESOLVER_HEADERS "include/smithy/identity/resolver/*.h" "include/smithy/identity/resolver/impl/*.h")
8082

@@ -109,6 +111,7 @@ file(GLOB UTILS_MEMORY_STL_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/utils/memo
109111
file(GLOB UTILS_STREAM_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/utils/stream/*.cpp")
110112
file(GLOB UTILS_CRYPTO_FACTORY_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/utils/crypto/factory/*.cpp")
111113
file(GLOB SMITHY_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/smithy/*.cpp")
114+
file(GLOB SMITHY_CLIENT_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/smithy/client/*.cpp")
112115
file(GLOB SMITHY_IDENTITY_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/smithy/identity/*.cpp")
113116
file(GLOB SMITHY_TRACING_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/smithy/tracing/*.cpp")
114117

@@ -287,6 +290,7 @@ file(GLOB AWS_NATIVE_SDK_COMMON_SRC
287290
${UTILS_MEMORY_STL_SOURCE}
288291
${UTILS_CRYPTO_CRT_SOURCE}
289292
${SMITHY_SOURCE}
293+
${SMITHY_CLIENT_SOURCE}
290294
${SMITHY_IDENTITY_SOURCE}
291295
${SMITHY_TRACING_SOURCE}
292296
)
@@ -328,8 +332,10 @@ file(GLOB AWS_NATIVE_SDK_COMMON_HEADERS
328332
${HTTP_CURL_CLIENT_HEADERS}
329333
${HTTP_WINDOWS_CLIENT_HEADERS}
330334
${SMITHY_HEADERS}
335+
${SMITHY_CLIENT_HEADERS}
331336
${SMITHY_TRACING_HEADERS}
332337
${SMITHY_IDENTITY_HEADERS}
338+
${SMITHY_IDENTITY_AUTH_HEADERS}
333339
${SMITHY_IDENTITY_IDENTITY_HEADERS}
334340
${SMITHY_IDENTITY_RESOLVER_HEADERS}
335341
${OPTEL_HEADERS}
@@ -448,7 +454,9 @@ if(MSVC)
448454
source_group("Header Files\\aws\\core\\external\\cjson" FILES ${CJSON_HEADERS})
449455
source_group("Header Files\\aws\\core\\external\\tinyxml2" FILES ${TINYXML2_HEADERS})
450456
source_group("Header Files\\smithy" FILES ${SMITHY_HEADERS})
457+
source_group("Header Files\\smithy\\client" FILES ${SMITHY_CLIENT_HEADERS})
451458
source_group("Header Files\\smithy\\tracing" FILES ${SMITHY_TRACING_HEADERS})
459+
source_group("Header Files\\smithy\\identity\\auth" FILES ${SMITHY_IDENTITY_AUTH_HEADERS})
452460
source_group("Header Files\\smithy\\identity\\identity" FILES ${SMITHY_IDENTITY_IDENTITY_HEADERS})
453461
source_group("Header Files\\smithy\\identity\\resolver" FILES ${SMITHY_IDENTITY_RESOLVER_HEADERS})
454462

@@ -497,6 +505,7 @@ if(MSVC)
497505
source_group("Source Files\\utils\\component-registry" FILES ${UTILS_COMPONENT_REGISTRY_SOURCE})
498506
source_group("Source Files\\utils\\memory\\stl" FILES ${UTILS_MEMORY_STL_SOURCE})
499507
source_group("Source Files\\smithy" FILES ${SMITHY_SOURCE})
508+
source_group("Source Files\\smithy\\client" FILES ${SMITHY_CLIENT_SOURCE})
500509
source_group("Source Files\\smithy\\identity" FILES ${SMITHY_IDENTITY_SOURCE})
501510
source_group("Source Files\\smithy\\tracing" FILES ${SMITHY_TRACING_SOURCE})
502511

@@ -707,8 +716,10 @@ install (FILES ${UTILS_THREADING_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/c
707716
install (FILES ${CJSON_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/external/cjson)
708717
install (FILES ${TINYXML2_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/external/tinyxml2)
709718
install (FILES ${SMITHY_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy)
719+
install (FILES ${SMITHY_CLIENT_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy/client)
710720
install (FILES ${SMITHY_TRACING_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy/tracing)
711721
install (FILES ${SMITHY_IDENTITY_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy/identity)
722+
install (FILES ${SMITHY_IDENTITY_AUTH_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy/identity/auth)
712723
install (FILES ${SMITHY_IDENTITY_IDENTITY_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy/identity/identity)
713724
install (FILES ${SMITHY_IDENTITY_RESOLVER_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/smithy/identity/resolver)
714725

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <smithy/Smithy_EXPORTS.h>
8+
9+
#include <aws/core/endpoint/AWSEndpoint.h>
10+
#include <aws/core/http/HttpRequest.h>
11+
#include <aws/core/AmazonWebServiceRequest.h>
12+
13+
#include <aws/core/utils/DateTime.h>
14+
#include <aws/core/utils/Outcome.h>
15+
16+
17+
namespace smithy
18+
{
19+
class AwsClientAsyncRequestCtx
20+
{
21+
public:
22+
using AwsCoreError = Aws::Client::AWSError<Aws::Client::CoreErrors>;
23+
using HttpResponseOutcome = Aws::Utils::Outcome<std::shared_ptr<Aws::Http::HttpResponse>, AwsCoreError>;
24+
25+
struct RequestInfo
26+
{
27+
Aws::Utils::DateTime ttl;
28+
long attempt;
29+
long maxAttempts;
30+
31+
explicit operator Aws::String() const
32+
{
33+
Aws::StringStream ss;
34+
if (ttl.WasParseSuccessful() && ttl != Aws::Utils::DateTime())
35+
{
36+
assert(attempt > 1);
37+
ss << "ttl=" << ttl.ToGmtString(Aws::Utils::DateFormat::ISO_8601_BASIC) << "; ";
38+
}
39+
ss << "attempt=" << attempt;
40+
if (maxAttempts > 0)
41+
{
42+
ss << "; max=" << maxAttempts;
43+
}
44+
return ss.str();
45+
}
46+
};
47+
48+
Aws::String m_invocationId;
49+
Aws::Http::HttpMethod m_method;
50+
const Aws::AmazonWebServiceRequest* m_pRequest; // optional
51+
52+
RequestInfo m_requestInfo;
53+
Aws::String m_requestName;
54+
std::shared_ptr<Aws::Http::HttpRequest> m_httpRequest;
55+
Aws::Endpoint::AWSEndpoint m_endpoint;
56+
57+
Aws::Crt::Optional<AwsCoreError> m_lastError;
58+
59+
size_t m_retryCount;
60+
Aws::Vector<void*> m_monitoringContexts;
61+
62+
std::function<void(HttpResponseOutcome)> m_responseHandler;
63+
std::shared_ptr<Aws::Utils::Threading::Executor> m_pExecutor;
64+
};
65+
} // namespace smithy
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <smithy/identity/auth/AuthOption.h>
8+
#include <smithy/identity/identity/AwsIdentity.h>
9+
#include <smithy/identity/resolver/AwsIdentityResolverBase.h>
10+
#include <smithy/identity/signer/AwsSignerBase.h>
11+
12+
#include <aws/core/utils/FutureOutcome.h>
13+
#include <aws/core/client/AWSError.h>
14+
#include <aws/core/http/HttpRequest.h>
15+
16+
#include <aws/crt/Variant.h>
17+
#include <aws/crt/Optional.h>
18+
#include <aws/core/utils/memory/stl/AWSMap.h>
19+
20+
#include <cassert>
21+
22+
23+
namespace smithy
24+
{
25+
template <typename AuthSchemesVariantT>
26+
class AwsClientRequestSigning
27+
{
28+
public:
29+
using HttpRequest = Aws::Http::HttpRequest;
30+
using SigningError = Aws::Client::AWSError<Aws::Client::CoreErrors>;
31+
using SigningOutcome = Aws::Utils::FutureOutcome<Aws::Http::HttpRequest, SigningError>;
32+
33+
static SigningOutcome SignRequest(const HttpRequest& HTTPRequest, const AuthOption& authOption,
34+
const Aws::UnorderedMap<Aws::String, AuthSchemesVariantT>& authSchemes)
35+
{
36+
auto authSchemeIt = authSchemes.find(authOption.schemeId);
37+
if (authSchemeIt == authSchemes.end())
38+
{
39+
assert(!"Auth scheme has not been found for a given auth option!");
40+
return (SigningError(Aws::Client::CoreErrors::CLIENT_SIGNING_FAILURE,
41+
"",
42+
"Requested AuthOption was not found within client Auth Schemes",
43+
false/*retryable*/));
44+
}
45+
46+
AuthSchemesVariantT authScheme = *authSchemeIt;
47+
48+
return SignWithAuthScheme(HTTPRequest, authScheme, authOption);
49+
}
50+
51+
protected:
52+
struct SignerVisitor
53+
{
54+
SignerVisitor(const HttpRequest& httpRequest, const AuthOption& targetAuthOption)
55+
: m_httpRequest(httpRequest), m_targetAuthOption(targetAuthOption)
56+
{
57+
}
58+
59+
const HttpRequest& m_httpRequest;
60+
const AuthOption& m_targetAuthOption;
61+
62+
Aws::Crt::Optional<SigningOutcome> result;
63+
64+
template <typename AuthSchemeAlternativeT>
65+
void operator()(AuthSchemeAlternativeT& authScheme)
66+
{
67+
// Auth Scheme Variant alternative contains the requested auth option
68+
assert(strcmp(authScheme.schemeId, m_targetAuthOption.schemeId) == 0);
69+
70+
using IdentityT = typename decltype(authScheme)::IdentityT;
71+
using IdentityResolver = IdentityResolverBase<IdentityT>;
72+
using Signer = AwsSignerBase<IdentityT>;
73+
74+
std::shared_ptr<IdentityResolver> identityResolver = authScheme.identityResolver();
75+
if (!identityResolver)
76+
{
77+
result.emplace(SigningError(Aws::Client::CoreErrors::CLIENT_SIGNING_FAILURE,
78+
"",
79+
"Auth scheme provided a nullptr identityResolver",
80+
false/*retryable*/));
81+
return;
82+
}
83+
84+
static_assert(
85+
std::is_same<IdentityResolverBase<IdentityT>, typename decltype(identityResolver
86+
)::IdentityT>::value);
87+
static_assert(std::is_base_of<IdentityResolverBase<IdentityT>, decltype(identityResolver)>::value);
88+
89+
IdentityT identity = identityResolver->getIdentity(m_targetAuthOption.identityProperties);
90+
91+
std::shared_ptr<Signer> signer = authScheme.signer();
92+
if (!signer)
93+
{
94+
result.emplace(SigningError(Aws::Client::CoreErrors::CLIENT_SIGNING_FAILURE,
95+
"",
96+
"Auth scheme provided a nullptr signer",
97+
false/*retryable*/));
98+
return;
99+
}
100+
101+
102+
static_assert(std::is_same<AwsSignerBase<IdentityT>, typename decltype(signer)::IdentityT>::value);
103+
static_assert(std::is_base_of<AwsSignerBase<IdentityT>, decltype(signer)>::value);
104+
105+
result.emplace(signer->sign(m_httpRequest, identity, m_targetAuthOption.signerProperties));
106+
}
107+
};
108+
109+
static
110+
SigningOutcome SignWithAuthScheme(const HttpRequest& HTTPRequest, const AuthSchemesVariantT& authSchemesVariant,
111+
const AuthOption& targetAuthOption)
112+
{
113+
SignerVisitor visitor(HTTPRequest, targetAuthOption);
114+
visitor.Visit(authSchemesVariant);
115+
116+
if (!visitor.result)
117+
{
118+
return (SigningError(Aws::Client::CoreErrors::CLIENT_SIGNING_FAILURE,
119+
"",
120+
"Failed to sign with an unknown error",
121+
false/*retryable*/));
122+
}
123+
return std::move(*visitor.result);
124+
}
125+
};
126+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <aws/crt/Variant.h>
8+
9+
#include <aws/core/utils/DateTime.h>
10+
#include <aws/core/utils/memory/stl/AWSMap.h>
11+
12+
namespace smithy {
13+
/* AuthOption and AuthOptionResolver */
14+
class AuthOption
15+
{
16+
using PropertyBag = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>;
17+
/* note: AuthOption is not connected with AuthScheme by type system, only by the String of schemeId, this is in accordance with SRA */
18+
public:
19+
static const char* schemeId;
20+
21+
PropertyBag identityProperties{};
22+
PropertyBag signerProperties{};
23+
};
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <smithy/identity/resolver/AwsIdentityResolverBase.h>
8+
#include <smithy/identity/signer/AwsSignerBase.h>
9+
10+
namespace smithy {
11+
template<uint64_t SCHEME_ID_HASH, typename IDENTITY_T>
12+
class AuthScheme
13+
{
14+
public:
15+
using IdentityT = IDENTITY_T;
16+
17+
static const uint64_t schemeId;
18+
19+
virtual ~AuthScheme() = default;
20+
21+
virtual std::shared_ptr<IdentityResolverBase<IdentityT>> identityResolver() = 0;
22+
23+
virtual std::shared_ptr<AwsSignerBase<IdentityT>> signer() = 0;
24+
};
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <smithy/identity/auth/AuthOption.h>
8+
#include <smithy/identity/signer/AwsSignerBase.h>
9+
10+
#include <aws/crt/Variant.h>
11+
#include <aws/core/utils/memory/stl/AWSMap.h>
12+
13+
namespace smithy {
14+
template<typename ServiceAuthSchemeParametersT = Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String, bool>>>
15+
class AuthSchemeResolverBase
16+
{
17+
public:
18+
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
19+
20+
virtual ~AuthSchemeResolverBase() = default;
21+
// AuthScheme Resolver returns a list of AuthOptions for some reason, according to the SRA...
22+
virtual std::vector<AuthOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) = 0;
23+
};
24+
}

0 commit comments

Comments
 (0)