Reputation: 11
I am currently trying to list all users using AWS IAM api and facing some difficulties. When after invoking the API through the WSO2 micro integrator it shows following error,
I have set the time zone to UTC in the deployed docker pod. To generate the signature I had to implement a custom class mediator and used the AWS recommended java implementation to generate the key.
package test;
import java.util.Calendar;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class IamConfigMediator extends AbstractMediator {
private static final String ACCESS_KEY = "XXXX";
private static final String SECRET_KEY = "XXXXXX";
private static final String region = "us-east-1";
private static final String serviceName = "iam";
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
public boolean mediate(MessageContext context) {
log.info("[IamConfigMediator] Generating SIGNATURE_HEADER and EXPIRE_TIME ##############################");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, 24);
long time = cal.getTimeInMillis();
String expireTime = formatTimestamp(time);
context.setProperty("EXPIRE_TIME", expireTime);
try {
byte[] signature = getSignatureKey(SECRET_KEY, expireTime, region, serviceName);
String header = "AWS4-HMAC-SHA256 Credential=" + ACCESS_KEY + "/" + expireTime + "/" + region + "/" + serviceName + "/aws4_request, SignedHeaders=host;x-amz-date, Signature=" + bytesToHex(signature);
context.setProperty("SIGNATURE_HEADER", header);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
static byte[] HmacSHA256(String data, byte[] key) throws Exception {
String algorithm = "HmacSHA256";
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(key, algorithm));
return mac.doFinal(data.getBytes("UTF-8"));
}
static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName) throws Exception {
byte[] kSecret = ("AWS4" + key).getBytes("UTF-8");
byte[] kDate = HmacSHA256(dateStamp, kSecret);
byte[] kRegion = HmacSHA256(regionName, kDate);
byte[] kService = HmacSHA256(serviceName, kRegion);
byte[] kSigning = HmacSHA256("aws4_request", kService);
return kSigning;
}
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
private static final DateTimeFormatter dateFormatter = DateTimeFormat
.forPattern("yyyyMMdd").withZoneUTC();
private static final DateTimeFormatter timeFormatter = DateTimeFormat
.forPattern("yyyyMMdd'T'HHmmss'Z'").withZoneUTC();
public static String formatTimestamp(long timeMilli) {
return timeFormatter.print(timeMilli);
}
}
Above implementation was used to generate the signature header("SIGNATURE_HEADER").
Upvotes: 1
Views: 215