Comment signer un Amazon web service à la demande .NET avec du SAVON et sans WSE
L'Amazon de la Publicité des Produits de l'API (anciennement partenaires d'Amazon Web Service ou Amazon AWS) a mis en place une nouvelle règle qui est par 15 août 2009, toutes les demandes de service web doit être signé. Ils ont fourni des exemples de code sur leur site montrant comment le faire en C# à l'aide de REST et SOAP. La mise en œuvre que j'utilise est du SAVON. Vous pouvez trouver un exemple de code ici, je ne suis pas compris, car il ya une bonne quantité.
Le problème, je vais avoir, c'est leur exemple de code utilise WSE 3 et notre code actuel n'utilise pas WSE. Quelqu'un sait-il comment mettre en place cette mise à jour, avec seulement l'aide de la génération automatique de code à partir du WSDL? J'aimerais ne pas avoir à basculer vers le WSE 3 trucs pour l'instant, si je n'ai pas à depuis cette mise à jour est plus rapide, patch pour nous tenir jusqu'à ce que nous pouvons pleinement mise en œuvre dans l'actuel dev version (3 août ils commencent à déposer 1 à 5 demandes, dans l'environnement direct, si elles ne sont pas signées, ce qui est une mauvaise nouvelle pour notre application).
Voici un extrait de la partie principale qui fait la signature de la requête SOAP.
class ClientOutputFilter : SoapFilter
{
//to store the AWS Access Key ID and corresponding Secret Key.
String akid;
String secret;
//Constructor
public ClientOutputFilter(String awsAccessKeyId, String awsSecretKey)
{
this.akid = awsAccessKeyId;
this.secret = awsSecretKey;
}
//Here's the core logic:
//1. Concatenate operation name and timestamp to get StringToSign.
//2. Compute HMAC on StringToSign with Secret Key to get Signature.
//3. Add AWSAccessKeyId, Timestamp and Signature elements to the header.
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
var body = envelope.Body;
var firstNode = body.ChildNodes.Item(0);
String operation = firstNode.Name;
DateTime currentTime = DateTime.UtcNow;
String timestamp = currentTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
String toSign = operation + timestamp;
byte[] toSignBytes = Encoding.UTF8.GetBytes(toSign);
byte[] secretBytes = Encoding.UTF8.GetBytes(secret);
HMAC signer = new HMACSHA256(secretBytes); //important! has to be HMAC-SHA-256, SHA-1 will not work.
byte[] sigBytes = signer.ComputeHash(toSignBytes);
String signature = Convert.ToBase64String(sigBytes); //important! has to be Base64 encoded
var header = envelope.Header;
XmlDocument doc = header.OwnerDocument;
//create the elements - Namespace and Prefix are critical!
XmlElement akidElement = doc.CreateElement(
AmazonHmacAssertion.AWS_PFX,
"AWSAccessKeyId",
AmazonHmacAssertion.AWS_NS);
akidElement.AppendChild(doc.CreateTextNode(akid));
XmlElement tsElement = doc.CreateElement(
AmazonHmacAssertion.AWS_PFX,
"Timestamp",
AmazonHmacAssertion.AWS_NS);
tsElement.AppendChild(doc.CreateTextNode(timestamp));
XmlElement sigElement = doc.CreateElement(
AmazonHmacAssertion.AWS_PFX,
"Signature",
AmazonHmacAssertion.AWS_NS);
sigElement.AppendChild(doc.CreateTextNode(signature));
header.AppendChild(akidElement);
header.AppendChild(tsElement);
header.AppendChild(sigElement);
//we're done
return SoapFilterResult.Continue;
}
}
Et qui est appelée lorsque l'appel de service web
//create an instance of the serivce
var api = new AWSECommerceService();
//apply the security policy, which will add the require security elements to the
//outgoing SOAP header
var amazonHmacAssertion = new AmazonHmacAssertion(MY_AWS_ID, MY_AWS_SECRET);
api.SetPolicy(amazonHmacAssertion.Policy());
Bonjour, oui nous avons un contact là-bas. Je vais voir sur la transmission du message.
OriginalL'auteur Brian Surowiec | 2009-07-30
Vous devez vous connecter pour publier un commentaire.
J'ai fini par mettre à jour le code pour utiliser WCF puisque c'est ce que c'est dans le courant dev version que j'ai travaillé. Ensuite, j'ai utilisé un code qui a été posté sur le Amazon forums, mais c'est un peu plus facile à utiliser.
Mise à JOUR: nouveau plus facile à utiliser le code qui vous permet de toujours utiliser les paramètres de configuration pour les tout
Dans le précédent code que j'ai posté, et ce que j'ai vu ailleurs, lorsque le service de création de l'objet de l'un des constructeur remplace est utilisé pour dire à utiliser le protocole HTTPS, donner l'url HTTPS et connecter manuellement le message de l'inspecteur qui font de la signature. La chute de ne pas utiliser le constructeur par défaut est de vous perdre la possibilité de configurer le service via le fichier de configuration.
Depuis, j'ai refait ce code, ainsi vous pouvez continuer à utiliser la valeur par défaut sans paramètre, le constructeur et configurer le service via le fichier de configuration. L'avantage de ceci est que vous n'avez pas à recompiler votre code pour l'utiliser, ou d'apporter des modifications une fois déployé comme à maxStringContentLength (qui est ce qui a causé ce changement de lieu, ainsi que de découvrir les chutes à le faire dans le code). J'ai aussi mis à jour la partie de signature un peu, de sorte que vous pouvez dire ce que l'algorithme de hachage à utiliser ainsi que la regex pour l'extraction de l'Action.
Ces deux modifications sont parce que tous les services web d'Amazon utilisent le même algorithme de hachage et de l'Action peut-être besoin d'être extraites de manière différente. Cela signifie que vous pouvez réutiliser le même code pour chaque type de service, en changeant juste ce qui est dans le fichier de configuration.
Pour l'utiliser, vous n'avez pas besoin de faire des changements à votre code existant, vous pouvez même mettre le code de signature dans une toute autre assemblée. Vous avez juste besoin de mettre en place la configuration de la section comme si (remarque: le numéro de version est important, sans lui correspondant le code ne sera pas de charger ou d'exécuter)
Oh, et +1 pour la réponse. Vous devez l'accepter.
J'ai mis en place un poste, y compris une procédure pas à pas et un exemple de projet démontrant accès à l'Amazone de la publicité des produits de l'API SOAP en utilisant WCF et signé des demandes à la flyingpies.wordpress.com/2009/08/01/17.
OriginalL'auteur Brian Surowiec
Salut Brian, je suis à la traitant de la même question dans mon application. Je suis en utilisant le WSDL généré code, en fait, j'ai généré un nouveau aujourd'hui pour assurer la dernière version. J'ai trouvé que la signature avec un certificat X509 le plus simple chemin. Avec quelques minutes de test sous ma ceinture, jusqu'à présent, il semble fonctionner ok. Essentiellement, vous changer::
Vipère au bytesblocks.com posté plus de détails, y compris la façon d'obtenir le certificat X509 Amazon génère pour vous.MODIFIER: la discussion sur la ici l'indique, ce n'est pas signer la demande. Affichera comme j'en apprendre davantage.
MODIFIER: cela n'apparaît pas de signer la demande. Au lieu de cela, il semble nécessiter une connexion https, et utilise le certificat SSL pour l'authentification du client. SSL, l'authentification du client est très peu utilisé en fonction de SSL. Il aurait été agréable si l'Amazon API de publicité de produit pris en charge comme un mécanisme d'authentification! Malheureusement, cela ne semble pas être le cas. La preuve en est double: (1) il n'est pas un documenté schémas d'authentification, et (2) qu'il n'a pas d'importance ce certificat que vous spécifiez.
Une certaine confusion est ajouté par Amazon toujours pas l'application de l'authentification sur les demandes, même après leur proclamée le 15 août 2009 date limite. Cela rend les demandes semblent passer correctement lorsque le certificat est ajouté, même si il pourrait ne pas ajouter de la valeur.
Regarder Brian Surowiec de réponse pour une solution qui fonctionne. Je pars de cette réponse ici pour le document de l'appel mais n'ont apparemment pas l'approche, que je peux encore le voir abordés dans les blogs et Amazon forums.
OriginalL'auteur Oren Trutner
Vous pouvez faire cela en utilisant la
ProtectionLevel
attributs. Voir La Compréhension Du Niveau De Protection De.OriginalL'auteur John Saunders
Le savon de mise en œuvre de la signature est kindof méchant. Je l'ai fait en PHP pour une utilisation sur http://www.apisigning.com/. Le truc que j'ai enfin compris, c'est que la Signature, AWSAccessKey, d'Horodatage et de paramètres besoin d'aller dans l'en-tête SOAP. Aussi, la Signature est juste un hachage de l'Opération + timestamp, et n'a pas besoin d'inclure tous les paramètres.
Je ne suis pas sûr de la façon qui s'adapte en C#, mais pensé qu'il pourrait être de quelque utilité
OriginalL'auteur Brandon