IBM / ibm-cos-sdk-java

ibm-cos-sdk-java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AmazonS3Client.generatePresignedUrl throws IllegalArgumentException: Access key cannot be null.

flindroth opened this issue · comments

Hello.

In my code, I'm trying to generate a presigned URL for downloading files through a browser. This is how I set up the AmazonS3Client:

return AmazonS3Client.builder()
                .withCredentials(new AWSStaticCredentialsProvider(new BasicIBMOAuthCredentials(cosCredentials.get("apikey"), cosCredentials.get("service_instance_id"))))
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region)).withPathStyleAccessEnabled(true)
                .withClientConfiguration(clientConfig)
                .build();

This is how I attempt to generate the presigned URL:

URL url = s3Client.generatePresignedUrl(
                bucketName,
                "document-" + documentId,
                Date.from(LocalDateTime.now().plusHours(1).toInstant(ZoneOffset.UTC)),
                HttpMethod.GET
        );

However, this makes the Amazon part of the library throws this IllegalArgumentException:

java.lang.IllegalArgumentException: Access key cannot be null.
	at com.amazonaws.auth.BasicAWSCredentials.<init>(BasicAWSCredentials.java:38) ~[ibm-cos-java-sdk-core-1.0.1.jar:na]
	at com.amazonaws.auth.AbstractAWSSigner.sanitizeCredentials(AbstractAWSSigner.java:426) ~[ibm-cos-java-sdk-core-1.0.1.jar:na]
	at com.amazonaws.services.s3.internal.S3QueryStringSigner.sign(S3QueryStringSigner.java:64) ~[ibm-cos-java-sdk-s3-1.0.1.jar:na]
	at com.amazonaws.services.s3.AmazonS3Client.presignRequest(AmazonS3Client.java:3018) ~[ibm-cos-java-sdk-s3-1.0.1.jar:na]
	at com.amazonaws.services.s3.AmazonS3Client.generatePresignedUrl(AmazonS3Client.java:2346) ~[ibm-cos-java-sdk-s3-1.0.1.jar:na]
	at com.amazonaws.services.s3.AmazonS3Client.generatePresignedUrl(AmazonS3Client.java:2274) ~[ibm-cos-java-sdk-s3-1.0.1.jar:na]

I have narrowed the cause down to these two methods in BasicIBMOAuthCredentials:

    public String getAWSAccessKeyId() {
        return null;
    }

    public String getAWSSecretKey() {
        return null;
    }

When such an object is supplied to AbstractAWSSigner.sanitizeCredentials, the resulting call to the BasicAWSCredentials constructor is with a null access key id and AWS secret key.

I wonder whether or not calling this API in this fashion is supported, and if not, how does one generate presigned URL:s?

Thanks for your help!

@atarian88 we are looking into this issue and will get back to you as soon as we can.

@atarian88 currently the java SDK does not support presigned urls with IAM credentials. You will need to use access & secret keys if possible. We will implement some updates to improve the message returned in this scenario.

Currently stuck on the same issue. Are there any sample code on how one can generate a public URL for downloading objects and work around this issue?

The credentials I have on IAM doesn't seem to have any secret keys included.

@geofreyflores see https://console.bluemix.net/docs/services/cloud-object-storage/libraries/java.html#java the createClient() method uses the BasicAWSCredentials Object. This implementation of AWSCredentials will work with presigned urls. You will need accessKey & secretKey details. Presigned urls are not supported with IAM credentials at present.