Skip to content

Commit

Permalink
Merge pull request #4 from aws/tempcred
Browse files Browse the repository at this point in the history
support for iam temp credential
  • Loading branch information
srondelli authored Sep 18, 2018
2 parents 18ea996 + 6ac65f9 commit 127cde8
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 11 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
target/
*.iml
*.iml
.idea/*
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<groupId>com.amazonaws</groupId>
<artifactId>amazon-neptune-sigv4-signer</artifactId>
<packaging>jar</packaging>
<version>1.0.3</version>
<version>1.0.4</version>

<name>amazon-neptune-sigv4-signer</name>
<description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static com.amazonaws.auth.internal.SignerConstants.AUTHORIZATION;
import static com.amazonaws.auth.internal.SignerConstants.HOST;
import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_DATE;
import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SECURITY_TOKEN;

/**
* Signer for HTTP requests made via Apache Commons {@link HttpUriRequest}s.
Expand Down Expand Up @@ -173,6 +174,14 @@ protected void attachSignature(final HttpUriRequest request, final NeptuneSigV4S
request.setHeader(HOST, signature.getHostHeader());
request.setHeader(X_AMZ_DATE, signature.getXAmzDateHeader());
request.setHeader(AUTHORIZATION, signature.getAuthorizationHeader());

// https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
// For temporary security credentials, it requires an additional HTTP header
// or query string parameter for the security token. The name of the header
// or query string parameter is X-Amz-Security-Token, and the value is the session token.
if (!signature.getSessionToken().isEmpty()) {
request.setHeader(X_AMZ_SECURITY_TOKEN, signature.getSessionToken());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static com.amazonaws.auth.internal.SignerConstants.AUTHORIZATION;
import static com.amazonaws.auth.internal.SignerConstants.HOST;
import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_DATE;
import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SECURITY_TOKEN;

/**
* Signer for HTTP requests made via Netty clients {@link FullHttpRequest}s.
Expand All @@ -52,7 +53,6 @@ public class NeptuneNettyHttpSigV4Signer extends NeptuneSigV4SignerBase<FullHttp
public NeptuneNettyHttpSigV4Signer(
final String regionName, final AWSCredentialsProvider awsCredentialsProvider)
throws NeptuneSigV4SignerException {

super(regionName, awsCredentialsProvider);
}

Expand Down Expand Up @@ -161,5 +161,13 @@ protected void attachSignature(final FullHttpRequest request, final NeptuneSigV4
request.headers().add(HOST, signature.getHostHeader());
request.headers().add(X_AMZ_DATE, signature.getXAmzDateHeader());
request.headers().add(AUTHORIZATION, signature.getAuthorizationHeader());

// https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
// For temporary security credentials, it requires an additional HTTP header
// or query string parameter for the security token. The name of the header
// or query string parameter is X-Amz-Security-Token, and the value is the session token.
if (!signature.getSessionToken().isEmpty()) {
request.headers().add(X_AMZ_SECURITY_TOKEN, signature.getSessionToken());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import static com.amazonaws.auth.internal.SignerConstants.AUTHORIZATION;
import static com.amazonaws.auth.internal.SignerConstants.HOST;
import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_DATE;
import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SECURITY_TOKEN;

/**
* Signer for HTTP requests encapsulalted in {@link RequestMetadata}s.
Expand Down Expand Up @@ -148,6 +149,14 @@ protected void attachSignature(final RequestMetadata request, final NeptuneSigV4
request.getHeaders().put(HOST, signature.getHostHeader());
request.getHeaders().put(X_AMZ_DATE, signature.getXAmzDateHeader());
request.getHeaders().put(AUTHORIZATION, signature.getAuthorizationHeader());

// https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
// For temporary security credentials, it requires an additional HTTP header
// or query string parameter for the security token. The name of the header
// or query string parameter is X-Amz-Security-Token, and the value is the session token.
if (!signature.getSessionToken().isEmpty()) {
request.getHeaders().put(X_AMZ_SECURITY_TOKEN, signature.getSessionToken());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.amazonaws.SignableRequest;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.http.HttpMethodName;
import com.amazonaws.util.SdkHttpUtils;

Expand Down Expand Up @@ -86,7 +87,6 @@ public NeptuneSigV4SignerBase(

checkNotNull(regionName, "The region name must not be null");
checkNotNull(awsCredentialsProvider, "The credentials provider must not be null");

this.awsCredentialsProvider = awsCredentialsProvider;

// initialize the signer delegate
Expand Down Expand Up @@ -134,7 +134,6 @@ public NeptuneSigV4SignerBase(
protected abstract void attachSignature(final T nativeRequest, final NeptuneSigV4Signature signature)
throws NeptuneSigV4SignerException;


/**
* Main logics to sign the request. The scheme is to convert the request into a
* signable request using toSignableRequest, then sign it using the AWS SDK, and
Expand All @@ -159,11 +158,19 @@ public void signRequest(final T request) throws NeptuneSigV4SignerException {
// 2. Sign the AWS SDK signable request (which internally adds some HTTP headers)
// => generic, using the AWS SDK signer
aws4Signer.sign(awsSignableRequest, awsCredentialsProvider.getCredentials());

// extract session token if temporary credentials are provided
String sessionToken = "";
if ((awsCredentialsProvider.getCredentials() instanceof BasicSessionCredentials)) {
sessionToken = ((BasicSessionCredentials) awsCredentialsProvider.getCredentials()).getSessionToken();
}

final NeptuneSigV4Signature signature =
new NeptuneSigV4Signature(
awsSignableRequest.getHeaders().get(HOST),
awsSignableRequest.getHeaders().get(X_AMZ_DATE),
awsSignableRequest.getHeaders().get(AUTHORIZATION));
awsSignableRequest.getHeaders().get(AUTHORIZATION),
sessionToken);

// 3. Copy over the Signature V4 headers to the original request
// => to be implemented in subclass
Expand Down Expand Up @@ -306,6 +313,11 @@ public static class NeptuneSigV4Signature {
*/
private final String authorizationHeader;

/**
* Value of the Temporary credential session token.
*/
private final String sessionToken;


/**
* Constructor.
Expand All @@ -315,10 +327,12 @@ public static class NeptuneSigV4Signature {
* @param authorizationHeader string value of the authorization header used for signing the request
*/
public NeptuneSigV4Signature(
final String hostHeader, final String xAmzDateHeader, final String authorizationHeader) {
final String hostHeader, final String xAmzDateHeader, final String authorizationHeader,
final String sessionToken) {
this.hostHeader = hostHeader;
this.xAmzDateHeader = xAmzDateHeader;
this.authorizationHeader = authorizationHeader;
this.sessionToken = sessionToken;
}

/**
Expand All @@ -341,5 +355,12 @@ public String getXAmzDateHeader() {
public String getAuthorizationHeader() {
return authorizationHeader;
}

/**
* @return the Session Token value
*/
public String getSessionToken() {
return sessionToken;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public abstract class NeptuneSigV4SignerAbstractTest<T> {
protected static final String TEST_QUERY_PARAM_NAME = "query";
protected static final String TEST_DATE_HEADER_VALUE = "2020/10/04";
protected static final String TEST_AUTHORIZATION_HEADER_VALUE = "Authorization Header";
protected static final String TEST_SESSION_TOKEN_VALUE = "Session Token";

protected final AWSCredentialsProvider awsCredentialsProvider = mock(AWSCredentialsProvider.class);

Expand Down Expand Up @@ -215,9 +216,7 @@ public void toSignableRequestGetNoHost() throws NeptuneSigV4SignerException {
signer.toSignableRequest(request);
}

@Test
public void attachSignatureHeaders() throws Exception {

private void testAttachSignatureHeaders(final String sessionToken) throws Exception {
// prep
final String uri = TEST_FULL_URI_WITH_SLASH;
final Map<String, String> requestHeaders = new HashMap<>();
Expand All @@ -230,7 +229,8 @@ public void attachSignatureHeaders() throws Exception {
final String dateHeader = TEST_DATE_HEADER_VALUE;
final String authHeader = TEST_AUTHORIZATION_HEADER_VALUE;

final NeptuneSigV4SignerBase.NeptuneSigV4Signature signature = new NeptuneSigV4SignerBase.NeptuneSigV4Signature(hostname, dateHeader, authHeader);
final NeptuneSigV4SignerBase.NeptuneSigV4Signature signature =
new NeptuneSigV4SignerBase.NeptuneSigV4Signature(hostname, dateHeader, authHeader, sessionToken);
signer.attachSignature(request, signature);

final Map<String, String> attachedHeaders = getRequestHeaders(request);
Expand All @@ -240,4 +240,16 @@ public void attachSignatureHeaders() throws Exception {
assertEquals(HEADER_TWO_VALUE, attachedHeaders.get(HEADER_TWO_NAME));
assertEquals(authHeader, attachedHeaders.get(SignerConstants.AUTHORIZATION));
}

@Test
public void attachSignatureHeadersWithSessionToken() throws Exception {
final String sessionToken = TEST_SESSION_TOKEN_VALUE;
testAttachSignatureHeaders(sessionToken);
}

@Test
public void attachSignatureHeadersWithEmptySessionToken() throws Exception {
final String sessionToken = "";
testAttachSignatureHeaders(sessionToken);
}
}

0 comments on commit 127cde8

Please sign in to comment.