Skip to content
This repository was archived by the owner on Jul 20, 2022. It is now read-only.

Aws blog athena custom jdbc credentials #101

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions aws-blog-athena-custom-jdbc-credentials/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Connecting to Amazon Athena with Federated Identities using Temporary Credentials

Using temporary security credentials ensures that access keys to protected resources in production are not directly hard-coded in the applications. Instead, you rely on AWS Secure Token Service (AWS STS) to generate temporary credentials.
Temporary security credentials work similar to the long-term access key credentials that your Amazon IAM users can use, with the following differences. These credentials are:
* Intended for short-term use only. You can configure these credentials to last for anywhere from a few minutes to several hours. After they expire, AWS no longer recognizes them, or allows any kind of access from API requests made with them.
* Not stored with the user, but are generated dynamically and provided to the user when requested. When (or even before) they expire, the user can request new credentials, as long as the user requesting them still has permissions to do so.

We list below some of the typical use cases in which your organization may require federated access to Amazon Athena:
1. Running Queries in Amazon Athena while Using Federation via SAML with Active Directory (AD). Your group requires to run queries in Amazon Athena while federating into AWS using SAML with permissions stored in AD.
2. Enabling Cross-Account Access to Amazon Athena for Users in Your Organization. A member of your group with access to AWS Account “A” needs to run Athena queries in Account “B”.
3. Enabling Access to Amazon Athena for a Data Application. A data application deployed on an Amazon EC2 instance needs to run Amazon Athena queries via JDBC.



### Pre-requisites


* Java 8 is installed
* SQL workbench is installed on your laptop or Windows EC2 instance.(http://www.sql-workbench.net/Workbench-Build123.zip)

#### SQL Workbench Extended Properties for SAML generated credentials

Property | Value
---------------------------|--------------------------------------------------------------------------------------
AwsCredentialsProviderClass|com.amazonaws.athena.jdbc.CustomIAMRoleAssumptionSAMLCredentialsProvider
AwsCredentialsProviderArguments|*access_key_id,secret_access_key,session token*
S3OutputLocation|s3://*bucket where athena results are stored*
LogPath|*local path on laptop or pc where logs are stored*
LogLevel|*LogLevel 1 thru 6*

#### SQL Workbench Extended Properties for Cross-Account Role Access

Property | Value
---------------------------|-----------------------------------------------------------------------
AwsCredentialsProviderClass|com.amazonaws.athena.jdbc.CustomIAMRoleAssumptionCredentialsProvider
AwsCredentialsProviderArguments|*access_key_id,secret_access_key,Cross Account Role ARN*
S3OutputLocation|s3://*bucket where athena results are stored*
LogPath|*local path on laptop or pc where logs are stored*
LogLevel|*LogLevel 1 thru 6*

#### SQL Workbench Extended Properties for EC2 Instance role

Property | Value
---------------------------|--------------------------------------------------------------------------------------
AwsCredentialsProviderClass|com.simba.athena.amazonaws.auth.InstanceProfileCredentialsProvider
S3OutputLocation|s3://*bucket where athena results are stored*
LogPath|*local path on laptop or pc where logs are stored*
LogLevel|*LogLevel 1 thru 6*
67 changes: 67 additions & 0 deletions aws-blog-athena-custom-jdbc-credentials/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.aws.labs</groupId>
<artifactId>athena-jdbc-custom-credentials-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>athena-jdbc</name>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>1.11.327</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-sts -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.11.327</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.327</version>
</dependency>
<dependency>
<groupId>com.syncron.amazonaws</groupId>
<artifactId>simba-athena-jdbc-driver</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<excludes>
<exclude>com.syncron.amazonaws:simba-athena-jdbc-driver:jar:2.0.2</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>com.syncron.amazonaws:simba-athena-jdbc-driver</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.amazonaws.custom.athena.jdbc;

import com.simba.athena.amazonaws.auth.AWSStaticCredentialsProvider;
import com.simba.athena.amazonaws.auth.BasicAWSCredentials;
import com.simba.athena.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;

public class CustomIAMRoleAssumptionCredentialsProvider implements com.amazonaws.auth.AWSCredentialsProvider{

private final AWSCredentials credentials;
private final String roleArn;
private AWSCredentials assumedCredentials;
private AWSSecurityTokenService stsClient;

//To use in JDBC: set aws_credentials_provider_class = "com.amazonaws.custom.athena.jdbc.CustomIAMRoleAssumptionCredentialsProvider"
// set AwsCredentialsProviderArguments = "<accessID>,<secretKey>,<roleArn>"
public CustomIAMRoleAssumptionCredentialsProvider(String accessId, String secretKey, String roleArn){

this.credentials = new BasicAWSCredentials(accessId,secretKey);
this.roleArn = roleArn;

stsClient = AWSSecurityTokenServiceClientBuilder.standard().withCredentials((com.amazonaws.auth.AWSCredentialsProvider) new AWSStaticCredentialsProvider(credentials)).build();

refresh();

}

public AWSCredentials getCredentials() {

return assumedCredentials;
}

public void refresh() {

AssumeRoleResult result = stsClient.assumeRole(new AssumeRoleRequest().withRoleArn(roleArn).withRoleSessionName("athenajdbc"));
assumedCredentials = getCredentialsFromAssumedRoleResult(result);

}

protected AWSCredentials getCredentialsFromAssumedRoleResult(AssumeRoleResult result){

return new BasicSessionCredentials(result.getCredentials().getAccessKeyId(),
result.getCredentials().getSecretAccessKey(),
result.getCredentials().getSessionToken());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.amazonaws.custom.athena.jdbc;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.simba.athena.amazonaws.auth.BasicSessionCredentials;

public class CustomIAMRoleAssumptionSAMLCredentialsProvider implements AWSCredentialsProvider{

private AWSCredentials credentials;

//To use in JDBC: set aws_credentials_provider_class = "com.amazonaws.custom.athena.jdbc.CustomIAMRoleAssumptionSAMLCredentialsProvider"
// set AwsCredentialsProviderArguments = "<accessID>,<secretKey>,<sessionToken>"
public CustomIAMRoleAssumptionSAMLCredentialsProvider(String accessId, String secretKey, String sessionToken){

this.credentials = new BasicSessionCredentials(accessId,secretKey,sessionToken);

}

public AWSCredentials getCredentials() {

return credentials;
}

public void refresh() {

//Use this method if refresh token is used
}



}