Comment transmettez-vous l'en-tête d'autorisation via API Gateway au point de terminaison HTTP?
J'ai une API derrière une API AWS Passerelle qui nécessite l'utilisation de l'en-tête d'Autorisation pour le traitement. Je n'ai malheureusement pas été en mesure de passer dans le backend pour le traitement.
J'ai essayé de créer l'Autorisation de la Requête HTTP en-Tête dans ma Méthode de Demande et de créer l'Autorisation correspondante en-Tête HTTP dans mon Intégration Demande (Autorisation est mappé à partir de la méthode.demande.l'en-tête.D'autorisation dans ce cas). Je me connecte tous les en-têtes que le backend reçoit, et dans le journal, je peux voir d'autres têtes que j'ai énumérés dans la Demande d'Intégration, mais pas d'Autorisation.
J'ai également essayé de créer un modèle de mappage avec le Type de Contenu application/json
et le modèle défini comme
{
"AccountID": "$context.identity.accountId",
"Caller": "$context.identity.caller",
"User": "$context.identity.user",
"Authorization": "$input.params().header.get('Authorization')",
"UserARN": "$context.identity.userArn"
}
Encore, le backend journaux montrent qu'il existe encore aucun en-tête d'Autorisation ni aucune Autorisation de terrain dans le JSON corps. Je ne peux pas voir le mode d'ARN. J'ai vu d'autres exemples et des discussions où les utilisateurs ont mentionné l'accès le champ d'Autorisation sur l'objet de l'événement qui est passé dans une fonction Lambda, mais je ne suis pas à l'aide d'une fonction Lambda.
J'ai fait en sorte de Déployer la Passerelle API dans les deux scénarios.
Personne ne sait si il y a une façon pour moi de passer à l'en-tête d'Autorisation par le biais de la Passerelle API de mon point de terminaison HTTP? Est-il un autre moyen pour accéder à l'API de l'appelant nom d'utilisateur ou ID?
Edit - Voici un extrait du code que j'utilise pour frapper la Passerelle 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();
}
}
Est assez bon pour s'authentifier avec succès et a frappé le point de terminaison HTTP sur le serveur principal.
source d'informationauteur Nick
Vous devez vous connecter pour publier un commentaire.
Comme indiqué dans les commentaires, l'Autorisation d'en-tête comprend des informations incomplètes pour vous de déterminer qui est l'utilisateur, de sorte que je ne recommande pas d'aller dans cette voie. En outre, si AWS_IAM auth est activé, l'en-tête d'Autorisation sera consommée par la Passerelle API.
Si AWS_IAM auth est activé et que la signature soit correctement alimenté, $contexte.l'identité paramètres devrait refléter les informations d'identification utilisées pour signer la demande.
Si vous utilisez le test invoquer la fonction dans la console, voyez-vous le contexte des champs remplis?
Mise à jour:
Je n'arrive pas à reproduire ce problème.
J'ai une API avec le mappage suivant modèle:
Et une fonction lambda que simplement recrache l'entrée comme à la sortie. Quand j'ai signer la demande et d'appeler les API, je rentre les résultats attendus:
Actuellement l'en-tête d'Autorisation ne peut être transmis, pour les méthodes qui ne nécessitent pas d'AWS authentification. Le SigV4 processus de signature repose sur l'en-tête d'Autorisation et nous n'exposez pas ce pour des raisons de sécurité. Si vous avez des données que vous avez besoin d'envoyer (en plus de l'SigV4 signature), vous devez l'envoyer dans un autre en-tête.
Dans d'API AWS de la Passerelle, du Corps de la Requête n'est pas prise en charge pour OBTENIR des méthodes.
Dans l'Intégration de Demande de convertir ton POST en précisant POSTE en tant que votre méthode HTTP. Puis procéder à la spécification de la carte du Corps Modèle proposé par @BobKinney
De cette façon, le corps de la requête se propagent correctement, mais le client sera toujours faire une requête GET comme prévu