diff --git a/core/http-auth-spi/pom.xml b/core/http-auth-spi/pom.xml index 416e3228a055..c366580aa013 100644 --- a/core/http-auth-spi/pom.xml +++ b/core/http-auth-spi/pom.xml @@ -54,6 +54,11 @@ reactive-streams ${reactive-streams.version} + + software.amazon.awssdk + identity-spi + ${awsjavasdk.version} + org.junit.jupiter diff --git a/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/HttpAuthOption.java b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/HttpAuthOption.java new file mode 100644 index 000000000000..f7f3ddc29ba2 --- /dev/null +++ b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/HttpAuthOption.java @@ -0,0 +1,90 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http.auth.spi; + +import software.amazon.awssdk.annotations.SdkProtectedApi; +import software.amazon.awssdk.http.auth.spi.internal.DefaultHttpAuthOption; +import software.amazon.awssdk.identity.spi.IdentityProperty; +import software.amazon.awssdk.utils.builder.SdkBuilder; + +/** + * An authentication scheme option, composed of the scheme ID and properties for use when resolving the identity and signing + * the request. + *

+ * This is used in the output from the auth scheme resolver. The resolver returns a list of these, in the order the auth scheme + * resolver wishes to use them. + * + * @see HttpAuthScheme + */ +@SdkProtectedApi +public interface HttpAuthOption { + + /** + * Get a new builder for creating a {@link HttpAuthOption}. + */ + static Builder builder() { + return new DefaultHttpAuthOption.BuilderImpl(); + } + + /** + * Retrieve the scheme ID, a unique identifier for the authentication scheme (aws.auth#sigv4, smithy.api#httpBearerAuth). + */ + String schemeId(); + + /** + * Retrieve the value of an {@link IdentityProperty}. + */ + T identityProperty(IdentityProperty property); + + /** + * Retrieve the value of an {@link SignerProperty}. + */ + T signerProperty(SignerProperty property); + + /** + * A method to operate on all {@link IdentityProperty} values of this HttpAuthOption. + */ + void forEachIdentityProperty(IdentityPropertyConsumer consumer); + + /** + * A method to operate on all {@link SignerProperty} values of this HttpAuthOption. + */ + void forEachSignerProperty(SignerPropertyConsumer consumer); + + /** + * Interface for operating on an {@link IdentityProperty} value. + */ + @FunctionalInterface + interface IdentityPropertyConsumer { + void accept(IdentityProperty propertyKey, T propertyValue); + } + + /** + * Interface for operating on an {@link SignerProperty} value. + */ + @FunctionalInterface + interface SignerPropertyConsumer { + void accept(SignerProperty propertyKey, T propertyValue); + } + + interface Builder extends SdkBuilder { + Builder schemeId(String schemeId); + + Builder putIdentityProperty(IdentityProperty key, T value); + + Builder putSignerProperty(SignerProperty key, T value); + } +} diff --git a/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/HttpAuthScheme.java b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/HttpAuthScheme.java new file mode 100644 index 000000000000..69b5d863bfdc --- /dev/null +++ b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/HttpAuthScheme.java @@ -0,0 +1,62 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http.auth.spi; + +import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; +import software.amazon.awssdk.identity.spi.Identity; +import software.amazon.awssdk.identity.spi.IdentityProvider; +import software.amazon.awssdk.identity.spi.TokenIdentity; + +/** + * An authentication scheme, composed of: + *

    + *
  1. A scheme ID - A unique identifier for the authentication scheme.
  2. + *
  3. An identity provider - An API that can be queried to acquire the customer's identity.
  4. + *
  5. A signer - An API that can be used to sign HTTP requests.
  6. + *
+ * + * @see IdentityProvider + * @see HttpSigner + * + * @param The type of the {@link Identity} used by this authentication scheme. + */ +@SdkPublicApi +public interface HttpAuthScheme { + + /** + * Retrieve the scheme ID, a unique identifier for the authentication scheme (aws.auth#sigv4, smithy.api#httpBearerAuth). + */ + String schemeId(); + + /** + * Retrieve the identity provider associated with this authentication scheme. The identity generated by this provider is + * guaranteed to be supported by the signer in this authentication scheme. + *

+ * For example, if the scheme ID is aws.auth#sigv4, the provider returns an {@link AwsCredentialsIdentity}, if the scheme + * ID is httpBearerAuth, the provider returns a {@link TokenIdentity}. + *

+ * Note, the returned identity provider may differ from the type of identity provider retrieved from the provided identity + * provider configuration. + */ + IdentityProvider identityProvider(IdentityProviderConfiguration providers); + + /** + * Retrieve the signer associated with this authentication scheme. This signer is guaranteed to support the identity + * generated by the identity provider in this authentication scheme. + */ + HttpSigner signer(); +} diff --git a/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/IdentityProviderConfiguration.java b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/IdentityProviderConfiguration.java new file mode 100644 index 000000000000..36b1bd842337 --- /dev/null +++ b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/IdentityProviderConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http.auth.spi; + +import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.identity.spi.Identity; +import software.amazon.awssdk.identity.spi.IdentityProvider; + +/** + * The identity providers configured in the SDK. + *

+ * Used by the {@link HttpAuthScheme} implementation to load any @{@link IdentityProvider}s it needs from the set that are + * configured on the SDK. + */ +@SdkPublicApi +@FunctionalInterface +public interface IdentityProviderConfiguration { + + /** + * Retrieve an identity provider for the provided identity type. + */ + IdentityProvider identityProvider(Class identityType); +} diff --git a/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/internal/DefaultHttpAuthOption.java b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/internal/DefaultHttpAuthOption.java new file mode 100644 index 000000000000..36acc96df21a --- /dev/null +++ b/core/http-auth-spi/src/main/java/software/amazon/awssdk/http/auth/spi/internal/DefaultHttpAuthOption.java @@ -0,0 +1,108 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http.auth.spi.internal; + +import java.util.HashMap; +import java.util.Map; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.http.auth.spi.HttpAuthOption; +import software.amazon.awssdk.http.auth.spi.SignerProperty; +import software.amazon.awssdk.identity.spi.IdentityProperty; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.Validate; + +@SdkInternalApi +public final class DefaultHttpAuthOption implements HttpAuthOption { + + private final String schemeId; + private final Map, Object> identityProperties; + private final Map, Object> signerProperties; + + DefaultHttpAuthOption(BuilderImpl builder) { + this.schemeId = Validate.paramNotBlank(builder.schemeId, "schemeId"); + this.identityProperties = new HashMap<>(builder.identityProperties); + this.signerProperties = new HashMap<>(builder.signerProperties); + } + + @Override + public String schemeId() { + return schemeId; + } + + @Override + public T identityProperty(IdentityProperty property) { + return (T) identityProperties.get(property); + } + + @Override + public T signerProperty(SignerProperty property) { + return (T) signerProperties.get(property); + } + + @Override + public void forEachIdentityProperty(IdentityPropertyConsumer consumer) { + for (IdentityProperty p : identityProperties.keySet()) { + IdentityProperty property = (IdentityProperty) p; + consumer.accept(property, this.identityProperty(property)); + } + } + + @Override + public void forEachSignerProperty(SignerPropertyConsumer consumer) { + for (SignerProperty p : signerProperties.keySet()) { + SignerProperty property = (SignerProperty) p; + consumer.accept(property, this.signerProperty(property)); + } + } + + @Override + public String toString() { + return ToString.builder("HttpAuthOption") + .add("identityProperties", identityProperties) + .add("signerProperties", signerProperties) + .build(); + } + + + public static final class BuilderImpl implements Builder { + private String schemeId; + private final Map, Object> identityProperties = new HashMap<>(); + private final Map, Object> signerProperties = new HashMap<>(); + + @Override + public Builder schemeId(String schemeId) { + this.schemeId = schemeId; + return this; + } + + @Override + public Builder putIdentityProperty(IdentityProperty key, T value) { + this.identityProperties.put(key, value); + return this; + } + + @Override + public Builder putSignerProperty(SignerProperty key, T value) { + this.signerProperties.put(key, value); + return this; + } + + @Override + public HttpAuthOption build() { + return new DefaultHttpAuthOption(this); + } + } +}