Skip to content

Commit da6a1b4

Browse files
committed
Add support for client level auth resolution with preferences
1 parent 04e8015 commit da6a1b4

File tree

16 files changed

+346
-132
lines changed

16 files changed

+346
-132
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,12 @@ namespace Aws
563563
std::chrono::milliseconds credentialCacheCacheTTL = std::chrono::minutes(50);
564564
} stsCredentialsProviderConfig;
565565
} credentialProviderConfig;
566+
567+
/**
568+
* Authentication scheme preferences in order of preference.
569+
* First available auth scheme will be used for each operation.
570+
*/
571+
Aws::Vector<Aws::String> authPreferences;
566572
};
567573

568574
/**

src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ namespace client
163163
identityParams.serviceName = m_serviceName;
164164
identityParams.operation = ctx.m_requestName;
165165
identityParams.region = m_clientConfiguration.region;
166+
identityParams.authPreferences = m_clientConfiguration.authPreferences;
166167

167168
if (ctx.m_pRequest) {
168169
// refactor once auth scheme resolver will use it's own rule set

src/aws-cpp-sdk-core/include/smithy/identity/auth/AuthSchemeResolverBase.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,23 @@
99

1010
#include <aws/crt/Variant.h>
1111
#include <aws/core/utils/memory/stl/AWSMap.h>
12-
12+
#include <aws/core/utils/memory/stl/AWSVector.h>
1313

1414
namespace smithy {
15+
16+
static char SIGV4_PREFERENCE[] = "sigv4";
17+
static char SIGV4A_PREFERENCE[] = "sigv4a";
18+
static char BEARER_PREFERENCE[] = "bearer";
19+
static char NO_AUTH_PREFERENCE[] = "noauth";
20+
21+
// Global map from auth scheme name (trimmed ID) to full ID for case insensitive lookup
22+
static const Aws::UnorderedMap<Aws::String, Aws::String> AUTH_SCHEME_NAME_TO_ID = {
23+
{SIGV4_PREFERENCE, "aws.auth#sigv4"},
24+
{SIGV4A_PREFERENCE, "aws.auth#sigv4a"},
25+
{BEARER_PREFERENCE, "smithy.api#HTTPBearerAuth"},
26+
{NO_AUTH_PREFERENCE, "smithy.api#noAuth"}
27+
};
28+
1529
/**
1630
* A base interface for code-generated interfaces for passing in the data required for determining the
1731
* authentication scheme. By default, this only includes the operation name.
@@ -22,6 +36,7 @@ class DefaultAuthSchemeResolverParameters
2236
Aws::String serviceName;
2337
Aws::String operation;
2438
Aws::Crt::Optional<Aws::String> region;
39+
Aws::Vector<Aws::String> authPreferences;
2540

2641
Aws::UnorderedMap<Aws::String, Aws::Crt::Variant<Aws::String,
2742
bool,
@@ -43,7 +58,31 @@ class AuthSchemeResolverBase
4358
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
4459

4560
virtual ~AuthSchemeResolverBase() = default;
46-
// AuthScheme Resolver returns a list of AuthSchemeOptions for some reason, according to the SRA...
47-
virtual Aws::Vector<AuthSchemeOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) = 0;
61+
62+
virtual Aws::Vector<AuthSchemeOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) {
63+
auto options = resolveAuthSchemeImpl(identityProperties);
64+
return filterByPreferences(options, identityProperties.authPreferences);
65+
}
66+
67+
protected:
68+
virtual Aws::Vector<AuthSchemeOption> resolveAuthSchemeImpl(const ServiceAuthSchemeParameters& identityProperties) = 0;
69+
70+
virtual Aws::Vector<AuthSchemeOption> filterByPreferences(const Aws::Vector<AuthSchemeOption>& options,
71+
const Aws::Vector<Aws::String>& preferences) {
72+
if (preferences.empty()) return options;
73+
74+
Aws::Vector<AuthSchemeOption> filtered;
75+
for (const auto& pref : preferences) {
76+
auto prefSchemeIt = AUTH_SCHEME_NAME_TO_ID.find(Aws::Utils::StringUtils::ToLower(pref.c_str()));
77+
if (prefSchemeIt == AUTH_SCHEME_NAME_TO_ID.end()) continue;
78+
for (const auto& option : options) {
79+
if (option.schemeId == prefSchemeIt->second) {
80+
filtered.push_back(option);
81+
break;
82+
}
83+
}
84+
}
85+
return filtered.empty() ? options : filtered;
86+
}
4887
};
4988
}

src/aws-cpp-sdk-core/include/smithy/identity/auth/built-in/BearerTokenAuthScheme.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <smithy/identity/signer/built-in/BearerTokenSigner.h>
1212
namespace smithy
1313
{
14+
constexpr char BEARER[] = "smithy.api#HTTPBearerAuth";
15+
1416
class BearerTokenAuthScheme : public AuthScheme<AwsBearerTokenIdentityBase>
1517
{
1618
public:
@@ -22,7 +24,7 @@ class BearerTokenAuthScheme : public AuthScheme<AwsBearerTokenIdentityBase>
2224
explicit BearerTokenAuthScheme(
2325
std::shared_ptr<AwsCredentialIdentityResolverT> identityResolver,
2426
const Aws::String &serviceName, const Aws::String &region)
25-
: AuthScheme("smithy.api#HTTPBearerAuth"),
27+
: AuthScheme(BEARER),
2628
m_identityResolver{identityResolver},
2729
m_signer{Aws::MakeShared<smithy::BearerTokenSigner>(
2830
"BearerTokenAuthScheme", serviceName, region)}

src/aws-cpp-sdk-core/include/smithy/identity/auth/built-in/BearerTokenAuthSchemeResolver.h

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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/AuthSchemeResolverBase.h>
8+
#include <smithy/identity/auth/built-in/SigV4aAuthSchemeOption.h>
9+
#include <smithy/identity/auth/built-in/SigV4AuthSchemeOption.h>
10+
#include <smithy/identity/auth/built-in/BearerTokenAuthSchemeOption.h>
11+
12+
13+
namespace smithy {
14+
template<typename ServiceAuthSchemeParametersT = DefaultAuthSchemeResolverParameters>
15+
class GenericAuthSchemeResolver : public AuthSchemeResolverBase<ServiceAuthSchemeParametersT>
16+
{
17+
public:
18+
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
19+
GenericAuthSchemeResolver(const Aws::Vector<AuthSchemeOption>& allowedAuth) : m_allowedAuth(allowedAuth) {}
20+
GenericAuthSchemeResolver() = default;
21+
virtual ~GenericAuthSchemeResolver() = default;
22+
23+
private:
24+
Aws::Vector<AuthSchemeOption> m_allowedAuth;
25+
26+
protected:
27+
Aws::Vector<AuthSchemeOption> resolveAuthSchemeImpl(const ServiceAuthSchemeParameters& identityProperties) override
28+
{
29+
AWS_UNREFERENCED_PARAM(identityProperties);
30+
return m_allowedAuth;
31+
}
32+
};
33+
}

src/aws-cpp-sdk-core/include/smithy/identity/auth/built-in/SigV4AuthSchemeResolver.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/aws-cpp-sdk-core/include/smithy/identity/auth/built-in/SigV4MultiAuthResolver.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,18 @@
1212
#include <smithy/identity/auth/built-in/SigV4aAuthSchemeOption.h>
1313
#include <smithy/identity/auth/built-in/SigV4AuthScheme.h>
1414

15+
/**
16+
* This is an auth scheme resolver prioritizing endpoints2.0 auth resolution
17+
* used for s3 which supersedes the model based auth resolution we do in GenericAuthResolver.
18+
*/
19+
1520
namespace smithy {
1621
template<typename EndPointProviderType, typename ClientConfigType,typename ServiceAuthSchemeParametersT = DefaultAuthSchemeResolverParameters>
1722
class SigV4MultiAuthSchemeResolver : public AuthSchemeResolverBase<ServiceAuthSchemeParametersT, ClientConfigType>
1823
{
19-
private:
2024
public:
25+
SigV4MultiAuthSchemeResolver(const Aws::Vector<AuthSchemeOption>& allowedAuth) : m_allowedAuth(allowedAuth) {}
26+
SigV4MultiAuthSchemeResolver() = default;
2127

2228
void Init(const ClientConfigType& config) override{
2329
m_endpointProviderForAuth = Aws::MakeShared<EndPointProviderType>("SigV4MultiAuthSchemeResolver");
@@ -27,8 +33,12 @@ namespace smithy {
2733
using ServiceAuthSchemeParameters = ServiceAuthSchemeParametersT;
2834
virtual ~SigV4MultiAuthSchemeResolver() = default;
2935

30-
Aws::Vector<AuthSchemeOption> resolveAuthScheme(const ServiceAuthSchemeParameters& identityProperties) override
36+
Aws::Vector<AuthSchemeOption> resolveAuthSchemeImpl(const ServiceAuthSchemeParameters& identityProperties) override
3137
{
38+
if (!m_allowedAuth.empty()) {
39+
// This code path will not currently be taken, but we should enable a way for the user to disable preference for endpoints2.0 resolution and use the preference list
40+
return m_allowedAuth;
41+
}
3242
//pack endpoint params from identityProperties
3343
Aws::Endpoint::EndpointParameters epParams;
3444

@@ -66,6 +76,10 @@ namespace smithy {
6676

6777
return {SigV4AuthSchemeOption::sigV4AuthSchemeOption};
6878
}
79+
80+
private:
81+
Aws::Vector<AuthSchemeOption> m_allowedAuth;
82+
6983
protected:
7084
std::shared_ptr<EndPointProviderType> m_endpointProviderForAuth;
7185
};

src/aws-cpp-sdk-core/include/smithy/identity/auth/built-in/SigV4aAuthSchemeResolver.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ Aws::String calculateRegion() {
188188
return "";
189189
}
190190

191+
192+
Aws::Vector<Aws::String> calculateAuthPreferences() {
193+
// Automatically determine the AWS region from environment variables, configuration file and EC2 metadata.
194+
Aws::Vector<Aws::String> res;
195+
auto prefs = Aws::Environment::GetEnv("AWS_AUTH_SCHEME_PREFERENCE");
196+
Aws::Vector<Aws::String> prefsList = StringUtils::Split(prefs, ',');
197+
for (auto& pref : prefsList) {
198+
res.push_back(StringUtils::Trim(pref.c_str()));
199+
}
200+
return res;
201+
}
202+
191203
void setLegacyClientConfigurationParameters(ClientConfiguration& clientConfig)
192204
{
193205
clientConfig.scheme = Aws::Http::Scheme::HTTPS;
@@ -251,6 +263,7 @@ void setLegacyClientConfigurationParameters(ClientConfiguration& clientConfig)
251263

252264
clientConfig.region = calculateRegion();
253265
clientConfig.credentialProviderConfig.region = clientConfig.region;
266+
clientConfig.authPreferences = calculateAuthPreferences();
254267

255268
// Set the endpoint to interact with EC2 instance's metadata service
256269
Aws::String ec2MetadataServiceEndpoint = Aws::Environment::GetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT");

0 commit comments

Comments
 (0)