Skip to content

Commit 1e23124

Browse files
committed
fix cache and threading concerns with STS Webidentity provider
1 parent d71a569 commit 1e23124

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace Aws
4242
void Reload() override;
4343

4444
private:
45+
bool ExpiresSoon() const;
46+
void RefreshIfExpired();
4547
enum class STATE {
4648
INITIALIZED,
4749
SHUT_DOWN,
@@ -50,6 +52,7 @@ namespace Aws
5052
std::condition_variable m_refreshSignal;
5153
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> m_credentialsProvider;
5254
std::chrono::milliseconds m_providerFuturesTimeoutMs;
55+
AWSCredentials m_credentials;
5356
};
5457
} // namespace Auth
5558
} // namespace Aws

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ using namespace Aws::Utils;
1414

1515
namespace {
1616
const char* STS_LOG_TAG = "STSAssumeRoleWebIdentityCredentialsProvider";
17+
const int STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD = 5 * 60 * 1000; // 5 Minutes.
1718
}
1819

1920
STSAssumeRoleWebIdentityCredentialsProvider::STSAssumeRoleWebIdentityCredentialsProvider(
@@ -76,9 +77,21 @@ STSAssumeRoleWebIdentityCredentialsProvider::STSAssumeRoleWebIdentityCredentials
7677
STSAssumeRoleWebIdentityCredentialsProvider::~STSAssumeRoleWebIdentityCredentialsProvider() = default;
7778

7879
AWSCredentials STSAssumeRoleWebIdentityCredentialsProvider::GetAWSCredentials() {
80+
// A valid client means required information like role arn and token file were constructed correctly.
81+
// We can use this provider to load creds, otherwise, we can just return empty creds.
82+
if (m_state != STATE::INITIALIZED)
83+
{
84+
return Aws::Auth::AWSCredentials();
85+
}
86+
RefreshIfExpired();
87+
Utils::Threading::ReaderLockGuard guard(m_reloadLock);
88+
return m_credentials;
89+
}
90+
91+
void STSAssumeRoleWebIdentityCredentialsProvider::Reload() {
7992
if (m_state != STATE::INITIALIZED) {
8093
AWS_LOGSTREAM_DEBUG(STS_LOG_TAG, "STSCredentialsProvider is not initialized, returning empty credentials");
81-
return AWSCredentials{};
94+
return;
8295
}
8396
AWSCredentials credentials{};
8497
auto refreshDone = false;
@@ -109,10 +122,25 @@ AWSCredentials STSAssumeRoleWebIdentityCredentialsProvider::GetAWSCredentials()
109122
if (!credentials.IsEmpty()) {
110123
credentials.AddUserAgentFeature(Aws::Client::UserAgentFeature::CREDENTIALS_STS_WEB_IDENTITY_TOKEN);
111124
}
125+
m_credentials = credentials;
126+
}
112127

113-
return credentials;
128+
bool STSAssumeRoleWebIdentityCredentialsProvider::ExpiresSoon() const {
129+
return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD);
114130
}
115131

116-
void STSAssumeRoleWebIdentityCredentialsProvider::Reload() {
117-
AWS_LOGSTREAM_DEBUG(STS_LOG_TAG, "Calling reload on STSCredentialsProvider is a no-op and no longer in the call path");
132+
void STSAssumeRoleWebIdentityCredentialsProvider::RefreshIfExpired() {
133+
Utils::Threading::ReaderLockGuard guard(m_reloadLock);
134+
if (!m_credentials.IsEmpty() && !ExpiresSoon())
135+
{
136+
return;
137+
}
138+
139+
guard.UpgradeToWriterLock();
140+
if (!m_credentials.IsExpiredOrEmpty() && !ExpiresSoon()) // double-checked lock to avoid refreshing twice
141+
{
142+
return;
143+
}
144+
145+
Reload();
118146
}

0 commit comments

Comments
 (0)