Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ public ClassName defaultAuthSchemeProviderName() {
return ClassName.get(internalPackage(), "Default" + providerInterfaceName().simpleName());
}

public ClassName modeledAuthSchemeProviderName() {
return ClassName.get(internalPackage(), "Modeled" + providerInterfaceName().simpleName());
public ClassName fallbackAuthSchemeProviderName() {
return ClassName.get(internalPackage(), "Fallback" + providerInterfaceName().simpleName());
}

public ClassName preferredAuthSchemeProviderName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@
import software.amazon.awssdk.utils.CompletableFutureUtils;
import software.amazon.awssdk.utils.Validate;

/**
* Generates an auth scheme provider that resolves authentication schemes from endpoint rules.
* <p>
* This class creates a provider that determines authentication schemes dynamically based on the resolved endpoint's auth scheme
* attributes. It first resolves the endpoint using endpoint rules, then extracts auth scheme information from the endpoint's
* attributes. If the endpoint doesn't specify auth schemes (for example, a custom endpoint provider is used), it delegates to the
* fallback provider, which returns the default auth schemes defined in {@link AuthTypeToSigV4Default}
* <p>
* The generated provider handles AWS signature versions (SigV4, SigV4a) and service-specific schemes (like S3 Express),
* translating endpoint auth scheme metadata into {@link AuthSchemeOption} instances with appropriate signer properties.
* <p>
* This provider is only generated for services with endpoint-based auth enabled
* ({@code isEnableEndpointAuthSchemeParams() = true}).
*/
public class EndpointBasedAuthSchemeProviderSpec implements ClassSpec {
private final AuthSchemeSpecUtils authSchemeSpecUtils;
private final EndpointRulesSpecUtils endpointRulesSpecUtils;
Expand Down Expand Up @@ -124,9 +138,9 @@ private MethodSpec endpointProvider() {
}

private FieldSpec modeledResolverInstance() {
return FieldSpec.builder(authSchemeSpecUtils.providerInterfaceName(), "MODELED_RESOLVER")
return FieldSpec.builder(authSchemeSpecUtils.providerInterfaceName(), "FALLBACK_RESOLVER")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.create()", authSchemeSpecUtils.modeledAuthSchemeProviderName())
.initializer("$T.create()", authSchemeSpecUtils.fallbackAuthSchemeProviderName())
.build();
}

Expand Down Expand Up @@ -159,7 +173,7 @@ private MethodSpec resolveAuthSchemeMethod() {
spec.addStatement("$T authSchemes = endpoint.attribute($T.AUTH_SCHEMES)",
ParameterizedTypeName.get(List.class, EndpointAuthScheme.class), AwsEndpointAttribute.class);
spec.beginControlFlow("if (authSchemes == null)");
spec.addStatement("return MODELED_RESOLVER.resolveAuthScheme(params)");
spec.addStatement("return FALLBACK_RESOLVER.resolveAuthScheme(params)");
spec.endControlFlow();


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@
import software.amazon.awssdk.codegen.poet.PoetUtils;
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;

/**
* Generates an auth scheme provider implementation based on the service model's authentication configuration.
* <p>
* This class creates a provider that resolves authentication schemes for SDK operations. It supports both
* service-level default auth schemes and per-operation auth scheme overrides. When operations have different
* auth requirements, it generates a switch statement to return the appropriate schemes based on the operation name.
* <p>
* The generated provider implements the auth scheme provider interface and returns an ordered list of
* {@link AuthSchemeOption} instances that the SDK will attempt in sequence during authentication.
* <p>
* <b>Usage Scenarios:</b>
* <ul>
* <li><b>Services without endpoint-based auth:</b> The generated class serves as the default auth scheme provider,
* directly implementing all auth scheme resolution logic based on the service model.</li>
*
* <li><b>Services with endpoint-based auth</b>(enabled through enableEndpointAuthSchemeParams customization config): The
* generated class is named with a "Fallback" prefix and works
* alongside the endpoint-based provider. It acts as a fallback when endpoint rules don't specify auth schemes, which could
* happen if the endpoint provider is overridden by users. The auth schemes are derived from hardcoded
* {@link AuthTypeToSigV4Default}</li>
* </ul>
*/
public class ModelBasedAuthSchemeProviderSpec implements ClassSpec {
private final AuthSchemeSpecUtils authSchemeSpecUtils;
private final AuthSchemeCodegenKnowledgeIndex knowledgeIndex;
Expand All @@ -43,7 +65,7 @@ public ModelBasedAuthSchemeProviderSpec(IntermediateModel intermediateModel) {
@Override
public ClassName className() {
if (authSchemeSpecUtils.useEndpointBasedAuthProvider()) {
return authSchemeSpecUtils.modeledAuthSchemeProviderName();
return authSchemeSpecUtils.fallbackAuthSchemeProviderName();
}
return authSchemeSpecUtils.defaultAuthSchemeProviderName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
public final class DefaultQueryAuthSchemeProvider implements QueryAuthSchemeProvider {
private static final DefaultQueryAuthSchemeProvider DEFAULT = new DefaultQueryAuthSchemeProvider();

private static final QueryAuthSchemeProvider MODELED_RESOLVER = ModeledQueryAuthSchemeProvider.create();
private static final QueryAuthSchemeProvider FALLBACK_RESOLVER = FallbackQueryAuthSchemeProvider.create();

private static final QueryEndpointProvider DELEGATE = QueryEndpointProvider.defaultProvider();

Expand All @@ -54,7 +54,7 @@ public List<AuthSchemeOption> resolveAuthScheme(QueryAuthSchemeParams params) {
Endpoint endpoint = CompletableFutureUtils.joinLikeSync(endpointProvider(params).resolveEndpoint(endpointParameters));
List<EndpointAuthScheme> authSchemes = endpoint.attribute(AwsEndpointAttribute.AUTH_SCHEMES);
if (authSchemes == null) {
return MODELED_RESOLVER.resolveAuthScheme(params);
return FALLBACK_RESOLVER.resolveAuthScheme(params);
}
List<AuthSchemeOption> options = new ArrayList<>();
for (EndpointAuthScheme authScheme : authSchemes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
public final class DefaultQueryAuthSchemeProvider implements QueryAuthSchemeProvider {
private static final DefaultQueryAuthSchemeProvider DEFAULT = new DefaultQueryAuthSchemeProvider();

private static final QueryAuthSchemeProvider MODELED_RESOLVER = ModeledQueryAuthSchemeProvider.create();
private static final QueryAuthSchemeProvider FALLBACK_RESOLVER = FallbackQueryAuthSchemeProvider.create();

private static final QueryEndpointProvider DELEGATE = QueryEndpointProvider.defaultProvider();

Expand All @@ -50,7 +50,7 @@ public List<AuthSchemeOption> resolveAuthScheme(QueryAuthSchemeParams params) {
Endpoint endpoint = CompletableFutureUtils.joinLikeSync(endpointProvider(params).resolveEndpoint(endpointParameters));
List<EndpointAuthScheme> authSchemes = endpoint.attribute(AwsEndpointAttribute.AUTH_SCHEMES);
if (authSchemes == null) {
return MODELED_RESOLVER.resolveAuthScheme(params);
return FALLBACK_RESOLVER.resolveAuthScheme(params);
}
List<AuthSchemeOption> options = new ArrayList<>();
for (EndpointAuthScheme authScheme : authSchemes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.services.query.auth.scheme.internal;

import java.util.ArrayList;
Expand All @@ -27,31 +26,31 @@

@Generated("software.amazon.awssdk:codegen")
@SdkInternalApi
public final class ModeledQueryAuthSchemeProvider implements QueryAuthSchemeProvider {
private static final ModeledQueryAuthSchemeProvider DEFAULT = new ModeledQueryAuthSchemeProvider();
public final class FallbackQueryAuthSchemeProvider implements QueryAuthSchemeProvider {
private static final FallbackQueryAuthSchemeProvider DEFAULT = new FallbackQueryAuthSchemeProvider();

private ModeledQueryAuthSchemeProvider() {
private FallbackQueryAuthSchemeProvider() {
}

public static ModeledQueryAuthSchemeProvider create() {
public static FallbackQueryAuthSchemeProvider create() {
return DEFAULT;
}

@Override
public List<AuthSchemeOption> resolveAuthScheme(QueryAuthSchemeParams params) {
List<AuthSchemeOption> options = new ArrayList<>();
switch (params.operation()) {
case "BearerAuthOperation":
options.add(AuthSchemeOption.builder().schemeId("smithy.api#httpBearerAuth").build());
break;
case "OperationWithNoneAuthType":
options.add(AuthSchemeOption.builder().schemeId("smithy.api#noAuth").build());
break;
default:
options.add(AuthSchemeOption.builder().schemeId("aws.auth#sigv4")
.putSignerProperty(AwsV4HttpSigner.SERVICE_SIGNING_NAME, "query-service")
.putSignerProperty(AwsV4HttpSigner.REGION_NAME, params.region().id()).build());
break;
case "BearerAuthOperation":
options.add(AuthSchemeOption.builder().schemeId("smithy.api#httpBearerAuth").build());
break;
case "OperationWithNoneAuthType":
options.add(AuthSchemeOption.builder().schemeId("smithy.api#noAuth").build());
break;
default:
options.add(AuthSchemeOption.builder().schemeId("aws.auth#sigv4")
.putSignerProperty(AwsV4HttpSigner.SERVICE_SIGNING_NAME, "query-service")
.putSignerProperty(AwsV4HttpSigner.REGION_NAME, params.region().id()).build());
break;
}
return Collections.unmodifiableList(options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import software.amazon.awssdk.services.s3.S3ServiceClientConfiguration;
import software.amazon.awssdk.services.s3.auth.scheme.S3AuthSchemeProvider;
import software.amazon.awssdk.services.s3.auth.scheme.internal.DefaultS3AuthSchemeProvider;
import software.amazon.awssdk.services.s3.auth.scheme.internal.ModeledS3AuthSchemeProvider;
import software.amazon.awssdk.services.s3.auth.scheme.internal.FallbackS3AuthSchemeProvider;
import software.amazon.awssdk.services.s3.internal.S3ServiceClientConfigurationBuilder;
import software.amazon.awssdk.services.s3.s3express.S3ExpressAuthScheme;

Expand Down Expand Up @@ -68,12 +68,12 @@ void s3Config_withDefaultS3AuthSchemeProvider_wrapsExistingProvider() {
@Test
void s3Config_withExistingModeledS3AuthSchemeProvider_wrapsExistingProvider() {
S3ServiceClientConfiguration.Builder s3Config = new S3ServiceClientConfigurationBuilder()
.authSchemeProvider(ModeledS3AuthSchemeProvider.create());
assertThat(s3Config.authSchemeProvider()).isInstanceOf(ModeledS3AuthSchemeProvider.class);
.authSchemeProvider(FallbackS3AuthSchemeProvider.create());
assertThat(s3Config.authSchemeProvider()).isInstanceOf(FallbackS3AuthSchemeProvider.class);

S3_EXPRESS_PLUGIN.configureClient(s3Config);
assertThat(s3Config.authSchemeProvider()).isInstanceOf(S3ExpressAuthSchemeProvider.class);
assertThat(getDelegateProvider(s3Config)).isInstanceOf(ModeledS3AuthSchemeProvider.class);
assertThat(getDelegateProvider(s3Config)).isInstanceOf(FallbackS3AuthSchemeProvider.class);
}

private S3AuthSchemeProvider getDelegateProvider(S3ServiceClientConfiguration.Builder s3Config) {
Expand Down
Loading