我在AWS API網關後面有一個API,需要使用Authorization標頭進行處理。不幸的是我無法將其傳遞給後端進行處理。如何通過API網關將授權標頭傳遞給HTTP端點?
我已經嘗試在我的方法請求中創建授權HTTP請求標頭,然後在集成請求中創建相應的授權HTTP標頭(授權從本例中的method.request.header.Authorization映射)。我記錄了後端收到的所有標題,並從日誌中可以看到集成請求中列出但未授權的其他標題。
我也曾嘗試創建與application/json
內容類型的映射模板,並定義爲
{
"AccountID": "$context.identity.accountId",
"Caller": "$context.identity.caller",
"User": "$context.identity.user",
"Authorization": "$input.params().header.get('Authorization')",
"UserARN": "$context.identity.userArn"
}
然而,後臺日誌顯示仍然沒有Authorization頭,也沒有任何授權領域的JSON體模板。我也看不到用戶的ARN。我已經看到用戶提到的其他示例和線程訪問傳遞到Lambda函數的事件對象上的授權字段,但我沒有使用Lambda函數。
我已經確保在兩種情況下部署API網關。
有誰知道是否有某種方法可以將授權標頭通過API網關傳遞給我的HTTP端點?有沒有其他方法可以訪問API調用者的用戶名或ID?
編輯 - 下面是我用打API網關的代碼片段:
String awsAccessKey = "myaccesskey";
String awsSecretKey = "mysecretkey";
URL endpointUrl;
try {
endpointUrl = new URL("https://<host>/<path>/<to>/<resource>?startDate=20151201&endDate=20151231");
} catch(Exception e) {
throw new RuntimeException("Unable to parse service endpoint: " + e.getMessage());
}
Date now = new Date();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
sdf1.setTimeZone(new SimpleTimeZone(0, "UTC"));
String dateTS = sdf1.format(now);
String headerNames = "host;x-amz-date";
String queryParameters = "endDate=20151231&startDate=20151201";
String canonicalRequest = "GET\n" +
"/<path>/<to>/<resource>\n" +
queryParameters + "\n" +
"host:<host>\n" +
"x-amz-date:" + dateTS + "\n" +
"\n" +
headerNames + "\n" +
"<sha256 hash for empty request body>";
System.out.println(canonicalRequest);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
sdf2.setTimeZone(new SimpleTimeZone(0, "UTC"));
String dateStr = sdf2.format(now);
String scope = dateStr + "/us-east-1/execute-api/aws4_request";
String stringToSign =
"AWS4-HMAC-SHA256\n" +
dateTS + "\n" +
scope + "\n" +
"hex encoded hash of canonicalRequest";
System.out.println(stringToSign);
byte[] kSecret = ("AWS4" + awsSecretKey).getBytes();
byte[] kDate = HmacSHA256(dateStr, kSecret);
byte[] kRegion = HmacSHA256("us-east-1", kDate);
byte[] kService = HmacSHA256("execute-api", kRegion);
byte[] kSigning = HmacSHA256("aws4_request", kService);
byte[] signature = HmacSHA256(stringToSign, kSigning);
String credentialsAuthorizationHeader = "Credential=" + awsAccessKey + "/" + scope;
String signedHeadersAuthorizationHeader = "SignedHeaders=" + headerNames;
String signatureAuthorizationHeader = "Signature=" + "hex encoded signature";
String authorization = "AWS4-HMAC-SHA256 "
+ credentialsAuthorizationHeader + ", "
+ signedHeadersAuthorizationHeader + ", "
+ signatureAuthorizationHeader;
Map<String, String> headers = new HashMap<String, String>();
headers.put("x-amz-date", dateTS);
headers.put("Host", endpointUrl.getHost());
headers.put("Authorization", authorization);
headers.put("Content-Type", "application/json");
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) endpointUrl.openConnection();
connection.setRequestMethod("GET");
for (String headerKey : headers.keySet()) {
connection.setRequestProperty(headerKey, headers.get(headerKey));
}
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream is;
try {
is = connection.getInputStream();
} catch (IOException e) {
is = connection.getErrorStream();
}
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
System.out.println(response.toString());
} catch (Exception e) {
throw new RuntimeException("Error: " + e.getMessage(), e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
這是不夠好,成功驗證,並砸在後端的HTTP端點。
只是爲了澄清自己的目標GET請求,你想Auhthorization頭或AWS身份驗證的結果?您是否爲該方法啓用AWS_IAM auth? –
我想授權標頭,其中包含簽名,憑證等。如果驗證標頭不能通過,我也可以使用一些關於調用者的信息(例如用戶ID)。是的,AWS_IAM爲資源啓用。 – Nick
您使用什麼驗證方法來訪問API? IAM用戶憑證,基於臨時STS角色的憑證,Cognito憑證? –