diff --git a/src/main/java/org/broad/igv/google/OAuthProvider.java b/src/main/java/org/broad/igv/google/OAuthProvider.java index 609a96a454..382b5ce73c 100644 --- a/src/main/java/org/broad/igv/google/OAuthProvider.java +++ b/src/main/java/org/broad/igv/google/OAuthProvider.java @@ -12,6 +12,7 @@ import org.broad.igv.util.AmazonUtils; import org.broad.igv.util.HttpUtils; import org.broad.igv.util.JWTParser; +import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.services.sts.model.Credentials; import java.awt.*; @@ -225,11 +226,13 @@ private void fetchTokens(String redirect) throws IOException { if (authProvider.equals("Amazon")) { // Get AWS credentials after getting relevant tokens - Credentials aws_credentials; - aws_credentials = AmazonUtils.GetCognitoAWSCredentials(); + if (!PreferencesManager.getPreferences().getUseAwsCredentialsChain()) { + Credentials aws_credentials; + aws_credentials = AmazonUtils.GetCognitoAWSCredentials(); - // Update S3 client with newly acquired token - AmazonUtils.updateS3Client(aws_credentials); + // Update S3 client with newly acquired token + AmazonUtils.updateS3Client(aws_credentials); + } } diff --git a/src/main/java/org/broad/igv/prefs/Constants.java b/src/main/java/org/broad/igv/prefs/Constants.java index 8fe4967f8d..60ac48045f 100644 --- a/src/main/java/org/broad/igv/prefs/Constants.java +++ b/src/main/java/org/broad/igv/prefs/Constants.java @@ -257,6 +257,7 @@ private Constants() {} // Prevent instantiation // OAuth provisioning public static final String PROVISIONING_URL = "PROVISIONING.URL"; + public static final String USE_AWS_CREDENTIALS_CHAIN = "PROVISIONING.USE_AWS_CREDENTIALS_CHAIN"; // Experimental public static final String SCORE_VARIANTS = "SCORE_VARIANTS"; diff --git a/src/main/java/org/broad/igv/prefs/IGVPreferences.java b/src/main/java/org/broad/igv/prefs/IGVPreferences.java index 74b7692210..aff5e3154b 100644 --- a/src/main/java/org/broad/igv/prefs/IGVPreferences.java +++ b/src/main/java/org/broad/igv/prefs/IGVPreferences.java @@ -375,6 +375,10 @@ public String getProvisioningURL() { return get(PROVISIONING_URL); } + public Boolean getUseAwsCredentialsChain() { + return getAsBoolean(USE_AWS_CREDENTIALS_CHAIN); + } + public String getPortNumber() { return get(PORT_NUMBER); } diff --git a/src/main/java/org/broad/igv/util/AmazonUtils.java b/src/main/java/org/broad/igv/util/AmazonUtils.java index 6c859cbea8..73201635c4 100644 --- a/src/main/java/org/broad/igv/util/AmazonUtils.java +++ b/src/main/java/org/broad/igv/util/AmazonUtils.java @@ -8,10 +8,13 @@ import org.broad.igv.aws.IGVS3Object; import org.broad.igv.google.OAuthProvider; import org.broad.igv.google.OAuthUtils; +import org.broad.igv.prefs.PreferencesManager; import org.broad.igv.ui.IGVMenuBar; import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.core.exception.SdkClientException; import software.amazon.awssdk.core.exception.SdkServiceException; import software.amazon.awssdk.regions.Region; @@ -36,6 +39,7 @@ import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Duration; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @@ -86,6 +90,16 @@ private static Region getAWSREGION() { return AWSREGION; } + /** + * Returns the AWS credentials + * + * @return returns the credentials based on the AWS STS access token returned from the AWS Cognito user pool. + */ + public static AwsCredentials GetProfileAWSCredentials(){ + ProfileCredentialsProvider profileCredentialsProv = ProfileCredentialsProvider.create(); + return profileCredentialsProv.resolveCredentials(); + } + /** * Returns the AWS credentials * @@ -167,7 +181,8 @@ public static Credentials GetCognitoAWSCredentials() { /** - * Makes sure the S3 client is available for bucket operations and/or generation of pre-signed urls + * Makes sure the S3 client is available for bucket operations and/or generation of pre-signed urls using + * Cognito Credentials * * @param credentials AWS credentials */ @@ -181,6 +196,19 @@ public static void updateS3Client(Credentials credentials) { } + /** + * Makes sure the S3 client is available for bucket operations and/or generation of pre-signed urls using + * Profile Credentials + * + * @param credentials AWS credentials + */ + +// public static void updateS3Client(AwsCredentials credentials) { +// StaticCredentialsProvider s3CredsProvider = StaticCredentialsProvider.create(credentials); +// s3Client = S3Client.builder().credentialsProvider(s3CredsProvider).build(); +// } + + /** * This method returns the details of the user and bucket lists. * @@ -188,8 +216,10 @@ public static void updateS3Client(Credentials credentials) { */ public static List ListBucketsForUser() { if (bucketsFinalList.isEmpty()) { - OAuthUtils.getInstance().getProvider("Amazon").getAccessToken(); - updateS3Client(GetCognitoAWSCredentials()); + if (!PreferencesManager.getPreferences().getUseAwsCredentialsChain()) { + OAuthUtils.getInstance().getProvider("Amazon").getAccessToken(); + updateS3Client(GetCognitoAWSCredentials()); + } List bucketsList = new ArrayList<>(); @@ -340,8 +370,10 @@ public static ArrayList ListBucketObjects(String bucketName, String ArrayList objects = new ArrayList<>(); log.debug("Listing objects for bucketName: " + bucketName); - OAuthUtils.getInstance().getProvider("Amazon").getAccessToken(); - updateS3Client(GetCognitoAWSCredentials()); + if (!PreferencesManager.getPreferences().getUseAwsCredentialsChain()) { + OAuthUtils.getInstance().getProvider("Amazon").getAccessToken(); + updateS3Client(GetCognitoAWSCredentials()); + } try { // https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html @@ -401,21 +433,29 @@ public static String getKeyFromS3URL(String s3URL) { // Amazon S3 Presign URLs // Also keeps an internal mapping between ResourceLocator and active/valid signed URLs. private static String createPresignedURL(String s3Path) throws IOException { - // Make sure access token are valid (refreshes token internally) - OAuthProvider provider = OAuthUtils.getInstance().getProvider("Amazon"); - provider.getAccessToken(); - - Credentials credentials = GetCognitoAWSCredentials(); - AwsSessionCredentials creds = AwsSessionCredentials.create(credentials.accessKeyId(), - credentials.secretAccessKey(), - credentials.sessionToken()); - StaticCredentialsProvider awsCredsProvider = StaticCredentialsProvider.create(creds); - - S3Presigner s3Presigner = S3Presigner.builder() - .expiration(provider.getExpirationTime()) - .awsCredentials(awsCredsProvider) - .region(getAWSREGION()) - .build(); + String presigned_url_string; + S3Presigner s3Presigner; + if (PreferencesManager.getPreferences().getUseAwsCredentialsChain()) { + s3Presigner = S3Presigner.builder() + .expiration(Duration.ofDays(7).minus(Duration.ofSeconds(2))) + .build(); + } else { + // Make sure access token are valid (refreshes token internally) + OAuthProvider provider = OAuthUtils.getInstance().getProvider("Amazon"); + provider.getAccessToken(); + + Credentials credentials = GetCognitoAWSCredentials(); + AwsSessionCredentials creds = AwsSessionCredentials.create(credentials.accessKeyId(), + credentials.secretAccessKey(), + credentials.sessionToken()); + StaticCredentialsProvider awsCredsProvider = StaticCredentialsProvider.create(creds); + + s3Presigner = S3Presigner.builder() + .expiration(provider.getExpirationTime()) + .awsCredentials(awsCredsProvider) + .region(getAWSREGION()) + .build(); + } String bucket = getBucketFromS3URL(s3Path); String key = getKeyFromS3URL(s3Path); @@ -448,8 +488,10 @@ public static Boolean isAwsS3Path(String path) { } public static void checkLogin() { - if (!OAuthUtils.getInstance().getProvider("Amazon").isLoggedIn()) { - OAuthUtils.getInstance().getProvider("Amazon").doSecureLogin(); + if (!PreferencesManager.getPreferences().getUseAwsCredentialsChain()) { + if (!OAuthUtils.getInstance().getProvider("Amazon").isLoggedIn()) { + OAuthUtils.getInstance().getProvider("Amazon").doSecureLogin(); + } } } diff --git a/src/main/resources/org/broad/igv/prefs/preferences.tab b/src/main/resources/org/broad/igv/prefs/preferences.tab index 10f33dda14..0322b5cf80 100644 --- a/src/main/resources/org/broad/igv/prefs/preferences.tab +++ b/src/main/resources/org/broad/igv/prefs/preferences.tab @@ -190,6 +190,7 @@ IGV.genome.sequence.dir Genome server URL string https://s3.amazonaws.com/igv.or MASTER_RESOURCE_FILE_KEY Data registry url string https://data.broadinstitute.org/igvdata/$$_dataServerRegistry.txt --- PROVISIONING.URL OAuth provisioning URL string null +PROVISIONING.USE_AWS_CREDENTIALS_CHAIN Use AWS native auth chain to use any supported AWS credential location boolean FALSE --- BLAT_URL Blat url String https://genome.cse.ucsc.edu/cgi-bin/hgBlat ---