Reputation: 29
I want to connect two S3 Buckets from spring boot Application. I make two different beans with different credentials and make one @primary now my application runs properly but when I tried to access second bucket which is not @primary It gives me 403 Access Denied Exception
com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;
Below is my code any help will be highly appreciated Thanks in Advance
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class AWSConfiguration {
@Value("${One.cloud.aws.credentials.accessKey}")
private String accessKeyOne;
@Value("${One.cloud.aws.credentials.secretKey}")
private String secretKeyOne;
@Value("${One.cloud.aws.region}")
private String regionOne;
@Value("${Two.bucket.accessKey}")
private String accessKeyTwo;
@Value("${Two.bucket.secretKey}")
private String secretKeyTwo;
@Value("${Two.bucket.region}")
private String regionTwo;
@Bean
@Primary
public BasicAWSCredentials basicAWSCredentialsOne() {
return new BasicAWSCredentials(accessKeyOne, secretKeyOne);
}
@Bean
@Primary
public AmazonS3 amazonS3ClientOne(AWSCredentials awsCredentials) {
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withCredentials(new AWSStaticCredentialsProvider(awsCredentials));
builder.setRegion(regionOne);
AmazonS3 amazonS3 = builder.build();
return amazonS3;
}
@Bean
public BasicAWSCredentials basicAWSCredentialsTwo() {
return new BasicAWSCredentials(accessKeyTwo, secretKeyTwo);
}
@Bean
public AmazonS3 amazonS3ClientTwo(AWSCredentials awsCredentials) {
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withCredentials(new AWSStaticCredentialsProvider(awsCredentials));
builder.setRegion(regionTwo);
AmazonS3 amazonS3 = builder.build();
return amazonS3;
}
}
Upvotes: 1
Views: 2425
Reputation: 12041
Is it necessary to expose both BasicAWSCredentials
as beans for your application? Can't you just inline the credentials like the following?
@Configuration
public class AWSConfiguration {
@Value("${One.cloud.aws.credentials.accessKey}")
private String accessKeyOne;
@Value("${One.cloud.aws.credentials.secretKey}")
private String secretKeyOne;
@Value("${One.cloud.aws.region}")
private String regionOne;
@Value("${Two.bucket.accessKey}")
private String accessKeyTwo;
@Value("${Two.bucket.secretKey}")
private String secretKeyTwo;
@Value("${Two.bucket.region}")
private String regionTwo;
@Bean
@Primary
public AmazonS3 amazonS3ClientOne(AWSCredentials awsCredentials) {
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKeyOne, secretKeyOne)));
builder.setRegion(regionOne);
AmazonS3 amazonS3 = builder.build();
return amazonS3;
}
@Bean
public AmazonS3 amazonS3ClientTwo(AWSCredentials awsCredentials) {
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKeyTwo, secretKeyTwo)));
builder.setRegion(regionTwo);
AmazonS3 amazonS3 = builder.build();
return amazonS3;
}
}
If you want to stick to your current approach with exposing both credentials as beans, you can have a look at the @Qualifier
annotation to specify the correct Credentials/AmzonS3 bucket instance while injecting them, e.g.
@Bean
public AmazonS3 amazonS3ClientTwo(@Qualifier("basicAWSCredentialsTwo") AWSCredentials awsCredentials) {
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withCredentials(new AWSStaticCredentialsProvider(awsCredentials));
builder.setRegion(regionTwo);
AmazonS3 amazonS3 = builder.build();
return amazonS3;
}
There is a good tutorial on Baeldung available for this.
Upvotes: 1