Skip to content

Commit 7f5f529

Browse files
committed
refactor common crt creds impl, add aws login provider
1 parent 8de5906 commit 7f5f529

File tree

14 files changed

+391
-205
lines changed

14 files changed

+391
-205
lines changed

prefetch_crt_dependency.sh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
# SPDX-License-Identifier: Apache-2.0.
44

55
CRT_URI_PREFIX=https://codeload.github.com/awslabs
6-
CRT_URI=${CRT_URI_PREFIX}/aws-crt-cpp/zip/35dad3a8131dc9d761a2ccfc24808308d5ce4680 # v0.35.2
6+
CRT_URI=${CRT_URI_PREFIX}/aws-crt-cpp/zip/2deaa9120dc23c03ab6feb903dd1d584d6cf7025 # v0.35.3
77

8-
AWS_C_AUTH_URI=${CRT_URI_PREFIX}/aws-c-auth/zip/ab03bdd996437d9097953ebb9495de71b6adc537 # v0.9.1
9-
AWS_C_CAL_URI=${CRT_URI_PREFIX}/aws-c-cal/zip/1b56db8ada9840e0e1036997ff4f247e155e51a5 # v0.9.8
10-
AWS_C_COMMON_URI=${CRT_URI_PREFIX}/aws-c-common/zip/31578beb2309330fece3fb3a66035a568a2641e7 # v0.12.5
8+
AWS_C_AUTH_URI=${CRT_URI_PREFIX}/aws-c-auth/zip/672feed19bb91bc389876f49aaa7c538dc879be5 # v0.9.2
9+
AWS_C_CAL_URI=${CRT_URI_PREFIX}/aws-c-cal/zip/de3b28840a59339f24012f25348f2c70a7ea45d6 # v0.9.11
10+
AWS_C_COMMON_URI=${CRT_URI_PREFIX}/aws-c-common/zip/95515a8b1ff40d5bb14f965ca4cbbe99ad1843df # v0.12.6
1111
AWS_C_COMPRESSION_URI=${CRT_URI_PREFIX}/aws-c-compression/zip/f951ab2b819fc6993b6e5e6cfef64b1a1554bfc8 # v0.3.1
1212
AWS_C_EVENT_STREAM_URI=${CRT_URI_PREFIX}/aws-c-event-stream/zip/31a44ff9108840a8f3fec54006218f4bc6c505e1 # v0.5.7
13-
AWS_C_HTTP_URI=${CRT_URI_PREFIX}/aws-c-http/zip/bbfc5a7bcf1a6c238205abcac62d5d14dd0da7ef # v0.10.5
14-
AWS_C_IO_URI=${CRT_URI_PREFIX}/aws-c-io/zip/1af325b54bba2e95a640a5be5ffe0b27e4ead79c # v0.23.2
13+
AWS_C_HTTP_URI=${CRT_URI_PREFIX}/aws-c-http/zip/07302aa4a2892adbbf95ee6d458db3bb240030d3 # v0.10.7
14+
AWS_C_IO_URI=${CRT_URI_PREFIX}/aws-c-io/zip/9cf142c08c28d5b1195aae09d2c05a6d17502e09 # v0.23.3
1515
AWS_C_MQTT_URI=${CRT_URI_PREFIX}/aws-c-mqtt/zip/1d512d92709f60b74e2cafa018e69a2e647f28e9 # v0.13.3
1616
AWS_C_S3_URI=${CRT_URI_PREFIX}/aws-c-s3/zip/332dd22c47a7ed139eee71e7f219b764ef8cdf4c # v0.9.2
1717
AWS_C_SDKUTILS_URI=${CRT_URI_PREFIX}/aws-c-sdkutils/zip/f678bda9e21f7217e4bbf35e0d1ea59540687933 # v0.2.4
1818
AWS_CHECKSUMS_URI=${CRT_URI_PREFIX}/aws-checksums/zip/9978ba2c33a7a259c1a6bd0f62abe26827d03b85 # v0.2.6
19-
AWS_LC_URI=${CRT_URI_PREFIX}/aws-lc/zip/5a9df2190d9ecab090a62030f94a6ada6789a436 # v1.62.0
20-
S2N_URI=${CRT_URI_PREFIX}/s2n/zip/30f40f2345a89570ed3c4cee2274942f1ebf85fa # v1.5.27
19+
AWS_LC_URI=${CRT_URI_PREFIX}/aws-lc/zip/7187ab572ddcdae4fa408e932d3e878c9941137b # v1.64.0
20+
S2N_URI=${CRT_URI_PREFIX}/s2n/zip/6aefe741f17489211f6c28e837c1a65ee66a1ef2 # v1.6.0
2121

2222

2323
echo "Removing CRT"
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
#pragma once
7+
8+
#include <aws/core/Core_EXPORTS.h>
9+
#include <aws/core/auth/AWSCredentialsProvider.h>
10+
11+
#include <atomic>
12+
#include <memory>
13+
14+
namespace Aws {
15+
namespace Crt {
16+
namespace Auth {
17+
class ICredentialsProvider;
18+
class Credentials;
19+
} // namespace Auth
20+
} // namespace Crt
21+
} // namespace Aws
22+
23+
namespace Aws {
24+
namespace Auth {
25+
/**
26+
* A utility class for wrapping a cached crt credentials provider.
27+
*/
28+
class AWS_CORE_API CrtCredentialsProvider : public AWSCredentialsProvider {
29+
public:
30+
explicit CrtCredentialsProvider(const std::function<std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider>()>& credentialsProviderFactory,
31+
std::chrono::milliseconds providerFuturesTimeoutMs, Aws::Client::UserAgentFeature userAgentFeature,
32+
const Aws::String& providerName);
33+
virtual ~CrtCredentialsProvider();
34+
35+
/**
36+
* Retrieves the credentials if found, otherwise returns empty credential set.
37+
*/
38+
AWSCredentials GetAWSCredentials() override;
39+
40+
private:
41+
enum class STATE {
42+
INITIALIZED,
43+
NOT_INITIALIZED,
44+
};
45+
46+
static AWSCredentials ExtractCredentialsFromCrt(const Aws::Crt::Auth::Credentials& crtCredentials);
47+
void Reload() override;
48+
void RefreshIfExpired();
49+
50+
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> m_credentialsProvider;
51+
AWSCredentials m_credentials;
52+
std::chrono::milliseconds m_providerFuturesTimeoutMs;
53+
Aws::Client::UserAgentFeature m_userAgentFeature;
54+
Aws::String m_providerName;
55+
STATE m_state{STATE::NOT_INITIALIZED};
56+
};
57+
} // namespace Auth
58+
} // namespace Aws
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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/core/Core_EXPORTS.h>
8+
#include <aws/core/auth/CrtCredentialsProvider.h>
9+
10+
namespace Aws {
11+
namespace Auth {
12+
/**
13+
* To support retrieving credentials of STS AssumeRole with web identity.
14+
* Note that STS accepts request with protocol of queryxml. Calling GetAWSCredentials() will trigger (if expired)
15+
* a query request using AWSHttpResourceClient under the hood.
16+
*/
17+
class AWS_CORE_API LoginCredentialsProvider : public CrtCredentialsProvider {
18+
public:
19+
LoginCredentialsProvider(const Aws::Client::ClientConfiguration::CredentialProviderConfiguration& config);
20+
~LoginCredentialsProvider() override;
21+
};
22+
} // namespace Auth
23+
} // namespace Aws

src/aws-cpp-sdk-core/include/aws/core/auth/STSCredentialsProvider.h

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,24 @@
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
55

6-
76
#pragma once
87

98
#include <aws/core/Core_EXPORTS.h>
109
#include <aws/core/auth/AWSCredentialsProvider.h>
11-
12-
#include <atomic>
13-
#include <memory>
10+
#include <aws/core/auth/CrtCredentialsProvider.h>
1411

1512
namespace Aws {
16-
namespace Crt {
1713
namespace Auth {
18-
class ICredentialsProvider;
19-
class Credentials;
20-
}
21-
}
22-
}
23-
24-
namespace Aws
25-
{
26-
namespace Auth
27-
{
28-
/**
29-
* To support retrieving credentials of STS AssumeRole with web identity.
30-
* Note that STS accepts request with protocol of queryxml. Calling GetAWSCredentials() will trigger (if expired)
31-
* a query request using AWSHttpResourceClient under the hood.
32-
*/
33-
class AWS_CORE_API STSAssumeRoleWebIdentityCredentialsProvider : public AWSCredentialsProvider
34-
{
35-
public:
36-
STSAssumeRoleWebIdentityCredentialsProvider();
37-
STSAssumeRoleWebIdentityCredentialsProvider(Aws::Client::ClientConfiguration::CredentialProviderConfiguration config);
38-
virtual ~STSAssumeRoleWebIdentityCredentialsProvider();
39-
40-
/**
41-
* Retrieves the credentials if found, otherwise returns empty credential set.
42-
*/
43-
AWSCredentials GetAWSCredentials() override;
44-
45-
protected:
46-
void Reload() override;
47-
48-
private:
49-
enum class STATE {
50-
INITIALIZED,
51-
SHUT_DOWN,
52-
} m_state{STATE::SHUT_DOWN};
53-
mutable std::mutex m_refreshMutex;
54-
mutable std::condition_variable m_refreshSignal;
55-
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> m_credentialsProvider;
56-
std::chrono::milliseconds m_providerFuturesTimeoutMs;
57-
58-
// Thread-safe credential fetch coordination
59-
mutable std::atomic<bool> m_refreshInProgress{false};
60-
mutable std::atomic<bool> m_refreshDone{false};
61-
mutable std::shared_ptr<AWSCredentials> m_pendingCredentials;
62-
63-
// Helper methods for credential retrieval
64-
AWSCredentials waitForSharedCredentials() const;
65-
AWSCredentials extractCredentialsFromCrt(const Aws::Crt::Auth::Credentials& crtCredentials) const;
66-
AWSCredentials fetchCredentialsAsync();
67-
};
68-
} // namespace Auth
69-
} // namespace Aws
14+
/**
15+
* To support retrieving credentials of STS AssumeRole with web identity.
16+
* Note that STS accepts request with protocol of queryxml. Calling GetAWSCredentials() will trigger (if expired)
17+
* a query request using AWSHttpResourceClient under the hood.
18+
*/
19+
class AWS_CORE_API STSAssumeRoleWebIdentityCredentialsProvider : public CrtCredentialsProvider {
20+
public:
21+
STSAssumeRoleWebIdentityCredentialsProvider();
22+
STSAssumeRoleWebIdentityCredentialsProvider(const Aws::Client::ClientConfiguration::CredentialProviderConfiguration& config);
23+
~STSAssumeRoleWebIdentityCredentialsProvider() override;
24+
};
25+
} // namespace Auth
26+
} // namespace Aws

src/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,23 @@ namespace Aws
562562
*/
563563
std::chrono::milliseconds credentialCacheCacheTTL = std::chrono::minutes(50);
564564
} stsCredentialsProviderConfig;
565+
struct LoginProviderConfig {
566+
/**
567+
* ARN for AWS login session.
568+
*/
569+
Aws::String loginSession{};
570+
571+
/**
572+
* Overrides the login cache directory. by default the cache directory
573+
* is located at `~/.aws/login/cache`.
574+
*/
575+
Aws::String loginCacheOverride{};
576+
577+
/**
578+
* Time out for the credentials future call.
579+
*/
580+
std::chrono::milliseconds retrieveCredentialsFutureTimeout = std::chrono::seconds(10);
581+
} loginCredentialProviderConfig;
565582
} credentialProviderConfig;
566583
};
567584

src/aws-cpp-sdk-core/include/aws/core/client/UserAgent.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ enum class UserAgentFeature {
4242
CREDENTIALS_SSO,
4343
CREDENTIALS_SSO_LEGACY,
4444
CREDENTIALS_PROFILE_SOURCE_PROFILE,
45+
CREDENTIALS_LOGIN,
4546
PROTOCOL_RPC_V2_CBOR,
4647
};
4748

src/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
*/
55

66
#include <aws/core/auth/AWSCredentialsProviderChain.h>
7-
#include <aws/core/auth/STSCredentialsProvider.h>
7+
#include <aws/core/auth/LoginCredentialsProvider.h>
88
#include <aws/core/auth/SSOCredentialsProvider.h>
9+
#include <aws/core/auth/STSCredentialsProvider.h>
910
#include <aws/core/client/ClientConfiguration.h>
1011
#include <aws/core/platform/Environment.h>
11-
#include <aws/core/utils/memory/AWSMemory.h>
1212
#include <aws/core/utils/StringUtils.h>
1313
#include <aws/core/utils/logging/LogMacros.h>
14+
#include <aws/core/utils/memory/AWSMemory.h>
1415

1516
using namespace Aws::Auth;
1617
using namespace Aws::Utils::Threading;
@@ -93,6 +94,7 @@ DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain(const Aws
9394
AddProvider(Aws::MakeShared<ProcessCredentialsProvider>(DefaultCredentialsProviderChainTag,config.profile));
9495
AddProvider(Aws::MakeShared<STSAssumeRoleWebIdentityCredentialsProvider>(DefaultCredentialsProviderChainTag, config));
9596
AddProvider(Aws::MakeShared<SSOCredentialsProvider>(DefaultCredentialsProviderChainTag,config.profile));
97+
AddProvider(Aws::MakeShared<LoginCredentialsProvider>(DefaultCredentialsProviderChainTag, config));
9698

9799
// General HTTP Credentials (prev. known as ECS TaskRole credentials) only available when ENVIRONMENT VARIABLE is set
98100
const auto relativeUri = Aws::Environment::GetEnv(GeneralHTTPCredentialsProvider::AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#include <aws/core/auth/CrtCredentialsProvider.h>
6+
#include <aws/core/client/UserAgent.h>
7+
#include <aws/core/utils/threading/ReaderWriterLock.h>
8+
#include <aws/crt/auth/Credentials.h>
9+
10+
using namespace Aws::Auth;
11+
using namespace Aws::Utils;
12+
using namespace Aws::Utils::Threading;
13+
14+
namespace {
15+
const int FIVE_MINUTES_IN_MILLIS = 5 * 60 * 1000;
16+
}
17+
18+
CrtCredentialsProvider::CrtCredentialsProvider(
19+
const std::function<std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider>()>& credentialsProviderFactory,
20+
std::chrono::milliseconds providerFuturesTimeoutMs, Aws::Client::UserAgentFeature userAgentFeature, const Aws::String& providerName)
21+
: m_credentialsProvider{credentialsProviderFactory()},
22+
m_providerFuturesTimeoutMs{providerFuturesTimeoutMs},
23+
m_userAgentFeature{userAgentFeature},
24+
m_providerName{providerName} {
25+
if (m_credentialsProvider && m_credentialsProvider->IsValid()) {
26+
m_state = STATE::INITIALIZED;
27+
}
28+
}
29+
30+
CrtCredentialsProvider::~CrtCredentialsProvider() = default;
31+
32+
AWSCredentials CrtCredentialsProvider::GetAWSCredentials() {
33+
if (m_state != STATE::INITIALIZED) {
34+
return AWSCredentials{};
35+
}
36+
RefreshIfExpired();
37+
const ReaderLockGuard guard(m_reloadLock);
38+
return m_credentials;
39+
}
40+
41+
void CrtCredentialsProvider::Reload() {
42+
AWSCredentials credentials{};
43+
std::mutex refresh_mutex{};
44+
std::condition_variable refresh_condition;
45+
bool refresh_complete{false};
46+
m_credentialsProvider->GetCredentials([&credentials, &refresh_mutex, &refresh_complete, &refresh_condition](
47+
const std::shared_ptr<Crt::Auth::Credentials>& crtCredentials, int errorCode) -> void {
48+
{
49+
const std::unique_lock<std::mutex> lock(refresh_mutex);
50+
(void)errorCode;
51+
credentials = ExtractCredentialsFromCrt(*crtCredentials);
52+
refresh_complete = true;
53+
}
54+
refresh_condition.notify_all();
55+
});
56+
57+
std::unique_lock<std::mutex> lock(refresh_mutex);
58+
refresh_condition.wait_for(lock, m_providerFuturesTimeoutMs, [&refresh_complete]() -> bool { return refresh_complete; });
59+
if (!credentials.IsEmpty()) {
60+
credentials.AddUserAgentFeature(m_userAgentFeature);
61+
}
62+
m_credentials = credentials;
63+
}
64+
65+
void CrtCredentialsProvider::RefreshIfExpired() {
66+
ReaderLockGuard guard(m_reloadLock);
67+
if (!m_credentials.IsEmpty() && !m_credentials.ExpiresSoon(FIVE_MINUTES_IN_MILLIS)) {
68+
return;
69+
}
70+
71+
guard.UpgradeToWriterLock();
72+
// double-checked lock to avoid refreshing twice
73+
if (!m_credentials.IsEmpty() && !m_credentials.ExpiresSoon(FIVE_MINUTES_IN_MILLIS)) {
74+
return;
75+
}
76+
77+
Reload();
78+
}
79+
80+
AWSCredentials CrtCredentialsProvider::ExtractCredentialsFromCrt(const Aws::Crt::Auth::Credentials& crtCredentials) {
81+
AWSCredentials credentials{};
82+
const auto accountIdCursor = crtCredentials.GetAccessKeyId();
83+
credentials.SetAWSAccessKeyId({reinterpret_cast<char*>(accountIdCursor.ptr), accountIdCursor.len});
84+
const auto secretKeyCursor = crtCredentials.GetSecretAccessKey();
85+
credentials.SetAWSSecretKey({reinterpret_cast<char*>(secretKeyCursor.ptr), secretKeyCursor.len});
86+
const auto expiration = crtCredentials.GetExpirationTimepointInSeconds();
87+
credentials.SetExpiration(DateTime{static_cast<double>(expiration)});
88+
const auto sessionTokenCursor = crtCredentials.GetSessionToken();
89+
credentials.SetSessionToken({reinterpret_cast<char*>(sessionTokenCursor.ptr), sessionTokenCursor.len});
90+
return credentials;
91+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#include <aws/core/Globals.h>
6+
#include <aws/core/auth/LoginCredentialsProvider.h>
7+
#include <aws/core/client/ClientConfiguration.h>
8+
#include <aws/core/client/UserAgent.h>
9+
#include <aws/crt/auth/Credentials.h>
10+
11+
using namespace Aws::Auth;
12+
using namespace Aws::Utils;
13+
14+
namespace {
15+
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> GetLoginCrtProvider(
16+
const Aws::Client::ClientConfiguration::CredentialProviderConfiguration& credentialsConfig,
17+
Aws::Crt::Io::ClientBootstrap* defaultClientBootstrap) {
18+
Aws::Crt::Auth::CredentialsProviderLoginConfig loginConfig{};
19+
loginConfig.Bootstrap = defaultClientBootstrap;
20+
Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitDefaultClient();
21+
const Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT);
22+
const auto tlsOptions = Aws::GetDefaultTlsConnectionOptions();
23+
if (tlsOptions) {
24+
loginConfig.TlsConnectionOptions = *tlsOptions;
25+
}
26+
loginConfig.LoginSession = credentialsConfig.loginCredentialProviderConfig.loginSession.c_str();
27+
loginConfig.LoginCacheOverride = credentialsConfig.loginCredentialProviderConfig.loginCacheOverride.c_str();
28+
loginConfig.LoginRegion = credentialsConfig.region.c_str();
29+
return Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderLogin(loginConfig);
30+
}
31+
} // namespace
32+
33+
LoginCredentialsProvider::LoginCredentialsProvider(
34+
const Aws::Client::ClientConfiguration::CredentialProviderConfiguration& credentialsConfig)
35+
: CrtCredentialsProvider{[&credentialsConfig]() -> std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> {
36+
return GetLoginCrtProvider(credentialsConfig, GetDefaultClientBootstrap());
37+
},
38+
credentialsConfig.loginCredentialProviderConfig.retrieveCredentialsFutureTimeout,
39+
Aws::Client::UserAgentFeature::CREDENTIALS_LOGIN, "LoginCredentialsProvider"} {}
40+
41+
LoginCredentialsProvider::~LoginCredentialsProvider() = default;

0 commit comments

Comments
 (0)