Wie gehen Sie pass-Authorization-header durch API-Gateway, HTTP-Endpunkt?
Habe ich eine API, die hinter einer AWS-API-Gateway muss mit dem Authorization-header für die Verarbeitung. Ich habe leider nicht in der Lage war, übergeben diese an das backend zur Verarbeitung.
Ich habe versucht das erstellen der Autorisierung der HTTP-Anfrage-Header in meine Methode Anforderung und erstellen der entsprechenden Autorisierung der HTTP-Header in meinem Integration Beantragen (Berechtigung zugeordnet ist, aus Methode.Anfrage.header.Authorization in diesem Fall). Ich log alle Header, dass das backend erhält, und aus der log kann ich sehen, andere Header, die ich aufgelistet haben, in die Integration Verlangen, aber nicht die Autorisierung.
Ich habe auch versucht, die Schaffung einer mapping-Vorlage mit Content-Type application/json
und die Vorlage definiert als
{
"AccountID": "$context.identity.accountId",
"Caller": "$context.identity.caller",
"User": "$context.identity.user",
"Authorization": "$input.params().header.get('Authorization')",
"UserARN": "$context.identity.userArn"
}
Doch die backend-logs zeigen, dass es noch keine Authorization-header noch irgendein Authorization-Feld im JSON-Körper. Ich kann auch nicht sehen des Benutzers ARN. Ich habe gesehen, andere Beispiele und threads, in denen Benutzer haben erwähnt, Zugriff auf den Authorization-Feld auf das event-Objekt übergeben wird, in eine Lambda-Funktion, aber ich bin nicht mit einem Lambda-Funktion.
Habe ich sicher gestellt, dass zum Bereitstellen der API-Gateway in beiden Szenarien.
Weiß jemand, ob es eine Möglichkeit gibt, kann ich pass den Authorization-header über die API-Gateway, HTTP-Endpunkt? Gibt es eine alternative Möglichkeit, um Zugriff auf die API aufrufende Benutzer name oder ID?
Bearbeiten - Hier ist ein Ausschnitt von dem code, den ich verwende, um Treffer in der API-Gateway:
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();
}
}
Dies ist gut genug, um zu authentifizieren, erfolgreich und trifft den HTTP-Endpunkt auf dem back-End.
Ich möchte, dass der Authorization-header, der enthält Signatur, Zugangsdaten, etc. Ich könnte auch einige Informationen über den Anrufer (z.B. Benutzer-ID), wenn die Authentifizierung header kann nicht Durchlaufen werden. Ja, AWS_IAM für die Ressource aktiviert ist.
Welche Authentifizierungs-Methode verwenden Sie, um Zugriff auf die API? IAM-Benutzer-Anmeldeinformationen, temporäre STS Rolle Anmeldeinformationen, Cognito Zugangsdaten?
Wir sind die Benutzer über die IAM-Benutzer-Anmeldeinformationen, die zum erstellen der Signatur, die der Benutzer fügt dann in die Header Ihrer Anfrage. Noch eine Frage: wenn mein Ziel ist, herauszufinden, den Namen des IAM-Benutzers, der authentifiziert ist und die Verwendung der API-Gateway, können wir die Authentifizierung der Ergebnisse zu tun, dass in irgendeiner Weise?
Nein, der Authorization-header wäre wahrscheinlich nutzlos für Sie, als das einzige, was im Lieferumfang enthalten ist die AcessKey und Unterschrift. Würden Sie implementieren müssen, um Ihr eigenes system für die Zuordnung, AccessKey-id, um einen bestimmten Benutzer.
InformationsquelleAutor Nick | 2016-01-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie bereits angemerkt in den Kommentaren, der Authorization-header enthält unvollständige Informationen für Sie, um festzustellen, wer der Benutzer ist, so würde ich nicht empfehlen, diesen Weg gehen. Darüber hinaus, wenn AWS_IAM auth aktiviert ist, wird der Authorization-header wird verzehrt werden durch das API-Gateway.
Wenn AWS_IAM auth aktiviert ist und die Signatur ist korrekt geliefert, die $context.identity-Parameter sollte spiegeln die Anmeldeinformationen, die zum signieren der Anforderung.
Wenn Sie die test-Funktion aufrufen in der Konsole sehen Sie die Kontext-Felder ausgefüllt?
Update:
Ich bin nicht in der Lage um dieses Problem zu reproduzieren.
Ich habe eine API mit dem folgenden mapping-Vorlage:
Und eine lambda-Funktion, die einfach spuckt zurück, die Eingabe als Ausgabe. Wenn ich signieren der Anforderung, und rufen Sie die API, bekomme ich wieder die erwarteten Ergebnisse:
das ist definitiv nicht ereignen sollte. Sind Sie positiv, Sie sind signing requests? Konnte Sie nach dem code, den Sie zum aufrufen der API?
Ich aktualisierte die Frage mit einem code snippet. Ich bin sicher, dass ich bin signing requests.
Ich entschuldige mich, aber ich bin nicht in der Lage um dieses Problem zu reproduzieren. Bitte stellen Sie sicher, dass Sie bereitgestellt haben, den API mit der aktualisierten Vorlage und haben AWS_IAM auth aktiviert.
Ich habe versucht, mit Hilfe der mapping-Vorlage, die Sie zur Verfügung gestellt, und auch überprüft, dass die API bereitgestellt wurde, mit AWS_IAM auth aktiviert. Leider sehe ich das gleiche Ergebnis: ich kann sehen, dass die erwarteten Felder im request-body, wenn die Anmeldung durch meine API, nachdem Sie die API-Gateway mit der Test-Funktionalität. Wenn ich auf den API-Gateway mit meinen code zur Verfügung gestellt, der Antrag geht durch meinen API und den request-body wird protokolliert, so leer. Alle Kopf-und den query-string gleich Aussehen, außer für x-forwarded-for-IP. Vielleicht kann ich versuchen es mit einem anderen Endpunkt und sehen, was passiert, irgendwann...
InformationsquelleAutor Bob Kinney
Derzeit der Authorization-header können nur weitergeleitet werden, für Methoden, die nicht erfordern AWS-Authentifizierung. Die SigV4 Unterzeichnung Prozess beruht auf der Authorization-header, und wir setzen diese für Zwecke der Gefahrenabwehr. Wenn Sie Daten haben, die Sie brauchen, um zu senden (neben der SigV4 Unterschrift), müssen Sie zum senden in einem anderen header.
InformationsquelleAutor RyanG
In der AWS-API-Gateway-Request-Body wird nicht unterstützt für GET-Methoden.
InformationsquelleAutor jlorie
Integration In Anfrage konvertieren Sie Ihre GET zu POST durch die Angabe "POST" als HTTP-Methode. Fahren Sie dann mit der Angabe des Body-Mapping-Vorlage wie vorgeschlagen von @BobKinney
Diese Weise den Hauptteil der Anfrage weitergibt richtig, aber der client wird noch eine GET-Anforderung als erwartet
InformationsquelleAutor malenkiy_scot