diff --git a/.gitignore b/.gitignore
index 0bdd78e..cc34d89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
target/
-*.iml
\ No newline at end of file
+*.iml
+.idea/*
diff --git a/pom.xml b/pom.xml
index 787c81e..1c6719a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
com.amazonaws
amazon-neptune-sigv4-signer
jar
- 1.0.3
+ 1.0.4
amazon-neptune-sigv4-signer
diff --git a/src/main/java/com/amazonaws/neptune/auth/NeptuneApacheHttpSigV4Signer.java b/src/main/java/com/amazonaws/neptune/auth/NeptuneApacheHttpSigV4Signer.java
index 578138b..5a85fd0 100644
--- a/src/main/java/com/amazonaws/neptune/auth/NeptuneApacheHttpSigV4Signer.java
+++ b/src/main/java/com/amazonaws/neptune/auth/NeptuneApacheHttpSigV4Signer.java
@@ -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.
@@ -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());
+ }
}
}
diff --git a/src/main/java/com/amazonaws/neptune/auth/NeptuneNettyHttpSigV4Signer.java b/src/main/java/com/amazonaws/neptune/auth/NeptuneNettyHttpSigV4Signer.java
index 85cd4e0..afac3fe 100644
--- a/src/main/java/com/amazonaws/neptune/auth/NeptuneNettyHttpSigV4Signer.java
+++ b/src/main/java/com/amazonaws/neptune/auth/NeptuneNettyHttpSigV4Signer.java
@@ -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.
@@ -52,7 +53,6 @@ public class NeptuneNettyHttpSigV4Signer extends NeptuneSigV4SignerBase 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
@@ -306,6 +313,11 @@ public static class NeptuneSigV4Signature {
*/
private final String authorizationHeader;
+ /**
+ * Value of the Temporary credential session token.
+ */
+ private final String sessionToken;
+
/**
* Constructor.
@@ -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;
}
/**
@@ -341,5 +355,12 @@ public String getXAmzDateHeader() {
public String getAuthorizationHeader() {
return authorizationHeader;
}
+
+ /**
+ * @return the Session Token value
+ */
+ public String getSessionToken() {
+ return sessionToken;
+ }
}
}
diff --git a/src/test/java/com/amazonaws/neptune/auth/NeptuneSigV4SignerAbstractTest.java b/src/test/java/com/amazonaws/neptune/auth/NeptuneSigV4SignerAbstractTest.java
index 325ca42..b61149d 100644
--- a/src/test/java/com/amazonaws/neptune/auth/NeptuneSigV4SignerAbstractTest.java
+++ b/src/test/java/com/amazonaws/neptune/auth/NeptuneSigV4SignerAbstractTest.java
@@ -60,6 +60,7 @@ public abstract class NeptuneSigV4SignerAbstractTest {
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);
@@ -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 requestHeaders = new HashMap<>();
@@ -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 attachedHeaders = getRequestHeaders(request);
@@ -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);
+ }
}