Ich habe eine API hinter einem AWS API Gateway, die den Berechtigungsheader für die Verarbeitung verwenden muss. Ich konnte dies leider nicht an das Backend zur Bearbeitung weitergeben.Wie übergeben Sie den Autorisierungsheader über das API-Gateway an den HTTP-Endpunkt?
Ich habe versucht, die Autorisierung HTTP Request Header in meiner Methode Anfrage und dann die Erstellung der entsprechenden Autorisierung HTTP-Header in meiner Integrationsanfrage (Autorisierung wird in diesem Fall von method.request.header.Authorization zugeordnet). Ich protokolliere alle Header, die das Backend empfängt, und aus dem Protokoll kann ich andere Header sehen, die ich in der Integrationsanforderung aber nicht Autorisierung aufgelistet habe.
ich auch versucht haben, eine Mapping-Vorlage mit Content-Type application/json
und die Vorlage als
{
"AccountID": "$context.identity.accountId",
"Caller": "$context.identity.caller",
"User": "$context.identity.user",
"Authorization": "$input.params().header.get('Authorization')",
"UserARN": "$context.identity.userArn"
}
Doch definiert Erstellen der Backend-Protokolle zeigen, dass es immer noch keine Authorization-Header ist noch ein Berechtigungsfeld im JSON-Körper . Ich kann den ARN des Benutzers auch nicht sehen. Ich habe andere Beispiele und Threads gesehen, bei denen Benutzer erwähnt haben, dass sie auf das Berechtigungsfeld des Ereignisobjekts zugreifen, das an eine Lambda-Funktion übergeben wird, aber ich verwende keine Lambda-Funktion.
Ich habe sichergestellt, das API-Gateway in beiden Szenarien bereitzustellen.
Weiß jemand, ob es eine Möglichkeit gibt, den Authorization-Header über das API-Gateway an meinen HTTP-Endpunkt zu übergeben? Gibt es eine alternative Möglichkeit, auf den Benutzernamen oder die ID des API-Aufrufers zuzugreifen?
Bearbeiten - Hier ist ein Ausschnitt des Codes des API-Gateway Ich verwende zu treffen:
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();
}
}
Das ist gut genug, um erfolgreich und treffen den HTTP-Endpunkt auf dem Back-End zu authentifizieren.
Sie Ihre Ziele zu klären, wollen Sie der Ahthorization-Header oder das Ergebnis der AWS-Authentifizierung? Haben Sie die AWS_IAM-Authentifizierung für die Methode aktiviert? –
Ich möchte die Authorization-Header, die Signatur, Anmeldeinformationen usw. enthält. Ich könnte auch einige Informationen über den Anrufer (z. B. Benutzer-ID) verwenden, wenn Authentication Header nicht durchgereicht werden kann. Ja, AWS_IAM ist für die Ressource aktiviert. – Nick
Welche Authentifizierungsmethode verwenden Sie für den Zugriff auf die API? IAM-Benutzeranmeldeinformationen, temporäre STS-rollenbasierte Anmeldeinformationen, Cognito-Anmeldeinformationen? –