diff --git a/hadoop-tools/hadoop-aws/pom.xml b/hadoop-tools/hadoop-aws/pom.xml index a37e08a3f8e1d..145316529c81a 100644 --- a/hadoop-tools/hadoop-aws/pom.xml +++ b/hadoop-tools/hadoop-aws/pom.xml @@ -417,6 +417,8 @@ com.amazonaws aws-java-sdk-bundle + + 1.12.167 compile diff --git a/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/OIDCTokenCredentialsProvider.java b/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/OIDCTokenCredentialsProvider.java new file mode 100644 index 0000000000000..104c4643d821d --- /dev/null +++ b/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/OIDCTokenCredentialsProvider.java @@ -0,0 +1,78 @@ +package org.apache.hadoop.fs.s3a; + +import org.apache.commons.lang.StringUtils; +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.WebIdentityTokenCredentialsProvider; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.ProviderUtils; +import org.slf4j.Logger; + +import java.io.IOException; + +/** + * WebIdentityTokenCredentialsProvider supports static configuration + * of OIDC token path, role ARN and role session name. + * + */ +//@InterfaceAudience.Public +//@InterfaceStability.Stable +public class OIDCTokenCredentialsProvider implements AWSCredentialsProvider { + public static final String NAME + = "org.apache.hadoop.fs.s3a.OIDCTokenCredentialsProvider"; + + //usually from import static org.apache.hadoop.fs.s3a.Constants.*; + public static final String JWT_PATH = "fs.s3a.jwt.path"; + public static final String ROLE_ARN = "fs.s3a.role.arn"; + public static final String SESSION_NAME = "fs.s3a.session.name"; + + /** Reuse the S3AFileSystem log. */ + private static final Logger LOG = S3AFileSystem.LOG; + + private String jwtPath; + private String roleARN; + private String sessionName; + private IOException lookupIOE; + + public OIDCTokenCredentialsProvider(Configuration conf) { + try { + Configuration c = ProviderUtils.excludeIncompatibleCredentialProviders( + conf, S3AFileSystem.class); + this.jwtPath = S3AUtils.lookupPassword(c, JWT_PATH, null); + this.roleARN = S3AUtils.lookupPassword(c, ROLE_ARN, null); + this.sessionName = S3AUtils.lookupPassword(c, SESSION_NAME, null); + } catch (IOException e) { + lookupIOE = e; + } + } + + public AWSCredentials getCredentials() { + if (lookupIOE != null) { + // propagate any initialization problem + throw new CredentialInitializationException(lookupIOE.toString(), + lookupIOE); + } + + LOG.debug("jwtPath {} roleARN {}", jwtPath, roleARN); + + if (!StringUtils.isEmpty(jwtPath) && !StringUtils.isEmpty(roleARN)) { + final AWSCredentialsProvider credentialsProvider = + WebIdentityTokenCredentialsProvider.builder() + .webIdentityTokenFile(jwtPath) + .roleArn(roleARN) + .roleSessionName(sessionName) + .build(); + return credentialsProvider.getCredentials(); + } + else throw new CredentialInitializationException( + "OIDC token path or role ARN is null"); + } + + public void refresh() {} + + @Override + public String toString() { + return getClass().getSimpleName(); + } + +}