Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use java to access dynamodb without access credential on an ec2 instance with IAM role

I want to use Java to access Dynamodb on an Ec2 instance. This Ec2 instance has been granted a IAM role, with which I can directly access the Dynamodb by using aws CLI: aws dynamodb list-table. Now I try to access the Dynamodb via Java. The Java code should be able to assume role, but it didn't work.

public static void main(String[] args) throws Exception {

    String ROLE_ARN = "arn:aws:iam::....";

    AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient();

    AssumeRoleRequest assumeRequest = new AssumeRoleRequest()
        .withRoleArn(ROLE_ARN)
        .withDurationSeconds(3600)
        .withRoleSessionName("demo");

    AssumeRoleResult assumeResult = stsClient.assumeRole(assumeRequest);

    BasicSessionCredentials temporaryCredentials = new BasicSessionCredentials(
                assumeResult.getCredentials().getAccessKeyId(),
                assumeResult.getCredentials().getSecretAccessKey(),
                assumeResult.getCredentials().getSessionToken());

    AmazonDynamoDBClient client = new AmazonDynamoDBClient(temporaryCredentials)

    DynamoDB dynamoDB = new DynamoDB(client);

    TableCollection<ListTablesResult> tables = dynamoDB.listTables();
    Iterator<Table> iterator_t = tables.iterator();
    System.out.println("Listing table names");
    while (iterator_t.hasNext()) {
        Table table = iterator_t.next();
        System.out.println(table.getTableName());
    }
}

When I ran the code on the ec2 instance, I got

Exception in thread "main" com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException: Not authorized to perform sts:AssumeRole (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 60313562-d462-11e6-a116-5bf8bb6a59ce)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1586)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1254)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1035)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:747)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:721)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:704)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:672)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:654)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:518)
    at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.doInvoke(AWSSecurityTokenServiceClient.java:1188)
    at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.invoke(AWSSecurityTokenServiceClient.java:1164)
    at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.assumeRole(AWSSecurityTokenServiceClient.java:419)
    at com.spokeo.dynamo_elas.AccessAwsD.main(AccessAwsD.java:stsClient.assumeRole(assumeRequest))

Anybody knows how to solve this problem? Thanks.

like image 928
ouyeyu Avatar asked Jan 06 '17 23:01

ouyeyu


People also ask

Why use an IAM role instead of the credentials?

When you use a role, you don't have to distribute long-term credentials (such as a user name and password or access keys) to an Amazon EC2 instance. Instead, the role supplies temporary permissions that applications can use when they make calls to other AWS resources.

How can DynamoDB be accessed from within a VPC without going through an Internet gateway?

A VPC endpoint for DynamoDB enables Amazon EC2 instances in your VPC to use their private IP addresses to access DynamoDB with no exposure to the public internet. Your EC2 instances do not require public IP addresses, and you don't need an internet gateway, a NAT device, or a virtual private gateway in your VPC.


2 Answers

After a long time exploring, finally figured out the following solution.

    AWSCredentialsProvider provider = new InstanceProfileCredentialsProvider();

    AWSCredentials credential = provider.getCredentials();

    AmazonDynamoDBClient client = new AmazonDynamoDBClient(credential);

    client.setRegion(Region.getRegion(Regions.US_WEST_2));

    DynamoDB dynamoDB = new DynamoDB(client);

    TableCollection<ListTablesResult> tables = dynamoDB.listTables();

Also the dependencies in pom.xml needs to be configured correctly to avoid conflicts, say, com.amazonaws aws-java-sdk 1.11.72

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor -->
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-cbor</artifactId>
        <version>2.8.5</version>
    </dependency>
like image 173
ouyeyu Avatar answered Oct 05 '22 18:10

ouyeyu


When I've done this I've never had to do anything specifically with the role - indeed, I have no idea what role I'm using. I use something like:

AWSCredentialsProviderChain credentialsProvider;
try {
    credentialsProvider = new DefaultAWSCredentialsProviderChain();
}
catch (Exception e) {
    throw new RuntimeException("Error loading credentials", e);
}

AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentialsProvider);

The advantage of using the default provider is that if I'm developing locally with a ~/.aws/credentials it is used. If I'm on the EC2 with IAM credentials then it is used.

like image 21
stdunbar Avatar answered Oct 05 '22 18:10

stdunbar