Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Signature et authentification des demandes REST
Rubriques
- Utilisation d'informations d'identification de sécurité temporaires
- L'en-tête Authentification
- Conversion sous forme canonique d'une demande pour signature
- Construction de l' CanonicalizedResource élément
- Construction de l' CanonicalizedAmzHeaders élément
- Éléments d'en-tête HTTP positionnels et éléments d'en-tête StringToSign HTTP nommés
- Exigence d'horodatage
- Exemples d'authentification
- Problèmes de signature de la demande REST
- Alternative à l'authentification d'une demande par chaîne d'interrogation
Note
Cette rubrique explique les demandes d'authentification à l'aide de la Signature Version 2. Amazon S3 prend désormais en charge le dernier processus Signature Version 4. Ce protocole récent est pris en charge dans toutes les Régions et chaque nouvelle Région après le 30 janvier 2014 prendra uniquement en charge Signature Version 4. Pour de plus amples informations, veuillez consulter Demandes d'authentification (AWS Signature Version 4) dans la Référence API Amazon Simple Storage Service.
L'authentification est le processus qui consiste à prouver l'identité au système. L'identité est un facteur important dans les décisions liées au contrôle d'accès Amazon S3. Les demandes sont autorisées ou refusées en partie en fonction l'identité du demandeur. Par exemple, le droit de créer des compartiments est réservé aux développeurs inscrits et (par défaut) le droit de créer des objets dans un compartiment est réservé au propriétaire du compartiment en question. En tant que développeur, vous faites des demandes qui appellent ces privilèges, vous devez donc prouver l'identité au système grâce à l'authentification des demandes. Cette section vous montre comment le faire.
Note
Le contenu de cette section ne s'applique pas à HTTP POST. Pour de plus amples informations, veuillez consulter Chargements basés sur le navigateur via POST (AWS Signature Version 2).
L'API REST Amazon S3 utilise un schéma HTTP personnalisé basé sur un HMAC (Hash Message Authentication Code) à clés pour l'authentification. Pour authentifier une demande, vous devez d'abord concaténer les éléments sélectionnés de la demande pour forme une chaîne. Utilisez ensuite la clé d'accès secrète AWS pour calculer le HMAC de cette chaîne. Officieusement, nous appelons ce processus « signature de la demande », et nous appelons le résultat de l'algorithme HMAC la signature, car elle imite les propriétés de sécurité d'une vraie signature. Enfin, vous ajoutez cette signature comme un paramètre de la demande grâce à la syntaxe décrite dans cette section.
Lorsque le système reçoit une demande authentifiée, il récupère la clé d'accès secrète AWS que vous dites posséder pour l'utiliser de la même manière afin de calculer une signature pour le message qu'il reçoit. Il compare ensuite la signature calculée et la signature présentée par le demandeur. Si les deux signatures correspondent, le système conclut que le demandeur doit avoir accès à la clé d'accès secrète AWS, et agit donc avec l'autorité du mandataire pour qui la clé a été émise. Si les deux signatures ne correspondent pas, la demande est abandonnée et le système répond par un message d'erreur.
Exemple Demande REST Amazon S3 authentifiée
GET /photos/puppy.jpg HTTP/1.1 Host: awsexamplebucket1.us-west-1.s3.amazonaws.com Date: Tue, 27 Mar 2007 19:36:42 +0000
Authorization: AWS AKIAIOSFODNN7EXAMPLE: qgk2+6Sv9/oM7G3qLEjTH1a1l1g=
Utilisation d'informations d'identification de sécurité temporaires
Si vous signez la demande grâce à des informations d'identification de sécurité temporaires (consultez Demandes), vous devez inclure le token de sécurité correspondant dans la demande et ajouter l'en-tête x-amz-security-token
.
Lorsque vous obtenez des informations d'identification de sécurité temporaires grâce à l'API AWS Security Token Service, la réponse inclut des informations d'identification de sécurité temporaires et un token de session. Vous indiquez la valeur du jeton de session dans l'en-tête x-amz-security-token
lorsque vous envoyez des demandes à Amazon S3. Pour de plus amples informations sur l'API AWS Security Token Service fournie par IAM, veuillez consulter Action dans le Guide de référence API AWS Security Token Service.
L'en-tête Authentification
L'API REST Amazon S3 utilise l'en-tête Authorization
HTTP standard pour transmettre les informations d'authentification. (Le nom de l'en-tête standard est maladroit car il comporte des informations d'authentification, pas d'autorisation.) Dans le schéma d'authentification Amazon S3, l'en-tête Autorisation possède la forme suivante :
Authorization: AWS
AWSAccessKeyId
:Signature
Les développeurs reçoivent un ID de clé d'accès AWS et une clé d'accès secrète AWS quand ils s'inscrivent. Pour une authentification de demande, l'élément AWSAccessKeyId
identifie l'ID de clé d'accès utilisé pour calculer la signature et, indirectement, le développeur à l'origine de la demande.
L'élément Signature
est le RFC 2104 HMAC-SHA1 des éléments sélectionnés issus de la demande, et donc la partie Signature
de l'en-tête Autorisation varie d'une demande à l'autre. Si la signature de la demande calculée par le système correspond à la Signature
incluse dans la demande, cela prouve que le demandeur possède la clé d'accès secrète AWS. La demande sera ensuite traitée sous l'identité, et avec l'autorité, du développeur pour qui la clé a été émise.
Voici une pseudo-grammaire qui illustre la construction de l'en-tête de la demande Authorization
. (Dans l'exemple, \n
signifie le point de code Unicode U+000A
, communément appelé nouvelle ligne).
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature; Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of(YourSecretAccessKey), UTF-8-Encoding-Of( StringToSign ) ) ); StringToSign = HTTP-Verb + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedAmzHeaders + CanonicalizedResource; CanonicalizedResource = [ "/" + Bucket ] + <HTTP-Request-URI, from the protocol name up to the query string> + [ subresource, if present. For example "?acl", "?location", or "?logging"]; CanonicalizedAmzHeaders = <described below>
HMAC-SHA1 est un algorithme défini par RFC 2104 - le hachage à clés pour l'authentification d'un messageYourSecretAccessKey
) comme clé, et l'encodage UTF-8 de StringToSign
comme message. Le résultat de HMAC-SHA1 est également une chaîne d'octets, appelée valeur de hachage. Le paramètre de la demande Signature
est construit en encodant en Base64 cette valeur de hachage.
Conversion sous forme canonique d'une demande pour signature
Rappelez-vous que lorsque le système reçoit une demande authentifiée, il compare la signature calculée de la demande et celle fournie dans la demande dans StringToSign
. C'est pourquoi, vous devez calculer la signature grâce à la même méthode utilisée par Amazon S3. Le processus qui consiste à mettre une demande dans une forme définie pour la signature est appelé conversion sous forme canonique.
Construction de l' CanonicalizedResource élément
CanonicalizedResource
représente la ressource Amazon S3 ciblée par la demande. Construisez-la pour une demande REST de la manière suivante :
1 |
Commencez par une chaîne de caractères vide ( |
2 |
Si la demande spécifie un compartiment qui utilise l'en-tête hôte HTTP (demande d'hébergement virtuel), ajoutez le nom du compartiment précédé d'un Pour une demande de type hébergement virtuel « https://awsexamplebucket1.s3.us-west-1.amazonaws.com/photos/puppy.jpg », le Pour une demande de type chemin d'accès, « https://s3.us-west-1.amazonaws.com/awsexamplebucket1/photos/puppy.jpg », le |
3 |
Ajoutez le chemin de la demande-URI HTTP non décodée, jusqu'à la chaîne d'interrogation mais sans l'inclure. Pour une demande de type hébergement virtuel « https://awsexamplebucket1.s3.us-west-1.amazonaws.com/photos/puppy.jpg », le Pour une demande de style chemin, « https://s3.us-west-1.amazonaws.com/awsexamplebucket1/photos/puppy.jpg », l’élément Pour une demande qui ne fait pas référence à un compartiment, comme GET Service, ajoutez « / ». |
4 |
Si la demande fait référence à une sous-ressource, comme Les sous-ressources qui doivent être incluses lors de la construction de l' CanonicalizedResource élément sont acl, lifecycle, location, logging, notification, partNumber, policy, requestPayment, UploadID, uploads, versionId, versionId, versioning, versions et site web. Si la demande spécifie des paramètres de la chaîne d'interrogation qui ignorent les valeurs de l'en-tête de la réponse (veuillez consulter GetObject), ajoutez les paramètres de la chaîne d'interrogation et leurs valeurs. Lors de la signature, vous n'encodez pas ces valeurs ; toutefois, lorsque vous faites la demande, vous devez encoder les valeurs de ces paramètres. Les paramètres de la chaîne d'interrogation dans une demande GET incluent Le paramètre de chaîne de |
Les éléments provenant de l' CanonicalizedResource URI de demande HTTP doivent être signés littéralement tels qu'ils apparaissent dans la requête HTTP, y compris les méta-caractères codés par URL.
La CanonicalizedResource
doit être différente de la demande-URI HTTP. En particulier, si la demande utilise l'en-tête Host
HTTP pour spécifier un compartiment, ce dernier n'apparaît pas dans la demande-URI HTTP. Toutefois, la CanonicalizedResource
continue d'inclure le compartiment. Les paramètres de la chaîne d'interrogation doivent également apparaître dans la demande-URI mais ne sont pas inclus dans la CanonicalizedResource
. Pour plus d’informations, consultez Hébergement virtuel de compartiments.
Construction de l' CanonicalizedAmzHeaders élément
Pour créer la CanonicalizedAmzHeaders partie deStringToSign
, sélectionnez tous les en-têtes de requête HTTP commençant par « x-amz- » (en utilisant une comparaison qui ne distingue pas les majuscules et minuscules), puis appliquez le processus suivant.
1 | Convertissez chaque nom d'en-tête HTTP en minuscule. Par exemple, « X-Amz-Date » devient « x-amz-date ». |
2 | Triez la sélection d'en-tête de manière lexicographique par nom d'en-tête. |
3 | Combinez les champs d'en-tête portant le même nom dans une paire « header-name : comma-separated-value-list » comme prescrit par la RFC 2616, section 4.2, sans espaces entre les valeurs. Par exemple, les deux en-têtes de métadonnées « x-amz-meta-username: fred » et « x-amz-meta-username: barney » seraient combinés en un seul en-tête « x-amz-meta-username:
fred,barney ». |
4 | « Séparez » les longs en-têtes qui s'étendent sur plusieurs lignes (comme le permet RFC 2616, section 4.2) en remplaçant le retour à la ligne (notamment la nouvelle ligne) par un espace simple. |
5 | Coupez les espaces autour des deux-points dans l'en-tête. Par exemple, l'en-tête « x-amz-meta-username: fred,barney » devient « x-amz-meta-username:fred,barney » |
6 | Enfin, ajoutez un caractère de nouvelle ligne (U+000A ) à chaque en-tête converti sous forme canonique dans la liste obtenue. Construisez l' CanonicalizedResource élément en concaténant tous les en-têtes de cette liste en une seule chaîne. |
Éléments d'en-tête HTTP positionnels et éléments d'en-tête StringToSign HTTP nommés
Les tout premiers éléments de l'en-tête de StringToSign
(Content-Type, Date et Content-MD5) sont positionnels par nature. StringToSign
n'inclut pas les noms de ces en-têtes, uniquement leurs valeurs de la demande. En revanche, les éléments « x-amz-
» sont nommés. Les noms et les valeurs de l'en-tête apparaissent dans StringToSign
.
Si un en-tête positionnel demandé pour une définition de StringToSign
n'est pas présent dans la demande (par exemple, les en-têtes Content-Type
ou Content-MD5
sont facultatifs pour les demandes PUT et insignifiants pour les demandes GET), substituez la chaîne de caractères vide ("") pour cette position.
Exigence d'horodatage
Un horodatage valide (qui utilise l'en-tête Date
HTTP ou une alternative x-amz-date
) est obligatoire pour les demandes authentifiées. De plus, l'horodatage du client inclus dans une demande authentifiée doit se faire dans les 15 minutes de l'heure du système Amazon S3 à la réception de la demande. Dans le cas contraire, la demande échoue avec le code d'erreur RequestTimeTooSkewed
. L'objectif de ces restrictions est de limiter la possibilité que des demandes interceptées soient réutilisées par un adversaire. Pour une meilleure protection contre l'écoute, utilisez le transport HTTPS pour des demandes authentifiées.
Note
La contrainte de validation sur la date de la demande s'applique uniquement aux demandes authentifiées qui n'utilisent pas d'authentification par chaîne d'interrogation. Pour de plus amples informations, veuillez consulter Alternative à l'authentification d'une demande par chaîne d'interrogation.
Certaines bibliothèques client HTTP n'offrent pas la possibilité de configurer l'en-tête Date
pour une demande. Si vous avez des problèmes pour inclure la valeur de l'en-tête « Date » dans les en-têtes convertis sous forme canonique, vous pouvez à la place configurer l'horodatage pour la demande grâce à un en-tête « x-amz-date
». La valeur de l'en-tête x-amz-date
doit être dans l'un des formats RFC 2616 (http://www.ietf.org/rfc/rfc2616.txtx-amz-date
est présent dans une demande, le système ignore tous les en-têtes Date
lors du calcul de la signature de la demande. Par conséquent, si vous incluez l'en-tête x-amz-date
, utilisez la chaîne de caractères vide pour la Date
lors de la création de l'élément StringToSign
. consultez suivante pour obtenir un exemple.
Exemples d'authentification
Les exemples de cette section utilisent les informations d'identification (qui ne fonctionnent pas) dans le tableau suivant.
Paramètre | Valeur |
---|---|
AWSAccessKeyId | AKIAIOSFODNN7EXAMPLE |
AWSSecretAccessKey | wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
Dans l'exemple StringToSign
, le formatage n'est pas significatif, et \n
signifie le point de code Unicode U+000A
, communément appelé nouvelle ligne. De plus, les exemples utilisent « +0000 » pour désigner le fuseau horaire. Vous pouvez utiliser « GMT » à la place pour désigner le fuseau horaire, mais les signatures illustrées dans les exemples sont différentes.
Objet GET
Cet exemple obtient un objet à partir du compartiment awsexamplebucket1.
Demande | StringToSign |
---|---|
|
|
Notez que le nom du compartiment est CanonicalizedResource inclus, mais pas l'URI de demande HTTP. (Le compartiment est spécifié par l'en-tête hôte.)
Note
Le script Python suivant calcule la signature précédente à l'aide des paramètres fournis. Vous pouvez utiliser ce script pour créer vos propres signatures, en remplaçant les clés, le cas StringToSign échéant.
import base64 import hmac from hashlib import sha1 access_key = '
AKIAIOSFODNN7EXAMPLE
'.encode("UTF-8") secret_key = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
'.encode("UTF-8") string_to_sign = 'GET\n\n\nTue, 27 Mar 2007 19:36:42 +0000\n/awsexamplebucket1/photos/puppy.jpg
'.encode("UTF-8") signature = base64.b64encode( hmac.new( secret_key, string_to_sign, sha1 ).digest() ).strip() print(f"AWS {access_key.decode()}:{signature.decode()}")
Objet PUT
Cet exemple place un objet dans le compartiment awsexamplebucket1.
Demande | StringToSign |
---|---|
|
|
Notez l'en-tête Content-Type dans la demande et dans le. StringToSign Notez également que le champ Content-MD5 est laissé vide dans le StringToSign, car il n'est pas présent dans la demande.
Liste
Cet exemple répertorie le contenu du compartiment awsexamplebucket1.
Demande | StringToSign |
---|---|
|
|
Notez la barre oblique finale CanonicalizedResource et l'absence de paramètres de chaîne de requête.
Fetch
Cet exemple récupère la stratégie de contrôle d'accès pour le compartiment « awsexamplebucket1 ».
Demande | StringToSign |
---|---|
|
|
Remarquez comment le paramètre de chaîne de requête de sous-ressource est inclus dans le CanonicalizedResource.
Suppression
Cet exemple supprime un objet du compartiment « awsexamplebucket1 » grâce à l'alternative de type chemin et Date.
Demande | StringToSign |
---|---|
|
|
Notez comment nous avons utilisé la méthode alternative x-amz-date « » pour spécifier la date (parce que notre bibliothèque cliente nous empêchait de définir la date, par exemple). Dans ce cas, le code x-amz-date
prime sur l'en-tête Date
. Par conséquent, l'entrée de la date dans la signature doit contenir la valeur de l'en-tête x-amz-date
.
Charger
Cet exemple charge un objet dans un compartiment d'hébergement virtuel CNAME avec des métadonnées.
Demande | StringToSign |
---|---|
|
|
Notez la façon dont les en-têtes sont triés, débarrassés de leurs espaces et convertis en minuscules. Notez également que plusieurs en-têtes avec le même nom ont été réunis grâce aux virgules pour séparer les valeurs.
Notez comme seuls les en-têtes d'entité HTTP Content-Type
et Content-MD5
apparaissent dans l'élément StringToSign
. Les autres en-têtes d'entité Content-*
n'apparaissent pas.
De nouveau, notez que la CanonicalizedResource
inclut le nom du compartiment, ce qui n'est pas le cas de la demande-URI HTTP. (Le compartiment est spécifié par l'en-tête hôte.)
Lister tous les compartiments
Demande | StringToSign |
---|---|
|
|
Clés Unicode
Demande | StringToSign |
---|---|
|
|
Note
Les éléments dans StringToSign
dérivés de la demande-URI sont pris littéralement, notamment l'encodage-URL et la casse.
Problèmes de signature de la demande REST
En cas d'échec de l'authentification de la demande REST, le système répond à la demande avec un rapport d'erreur XML. Les informations contenues dans ce rapport d'erreur aident les développeurs à identifier le problème. L'élément StringToSign
du rapport d'erreur SignatureDoesNotMatch
vous indique notamment la conversion sous forme canonique de la demande utilisée par le système.
Certaines boîtes à outils insèrent en silence et au préalable des en-têtes comme l'en-tête Content-Type
lors d'une opération PUT. Dans la plupart des cas, la valeur de l'en-tête inséré reste constante, ce qui vous permet d'identifier les en-têtes manquants grâce à des outils comme Ethereal ou tcpmon.
Alternative à l'authentification d'une demande par chaîne d'interrogation
Vous pouvez authentifier certains types de demandes en transférant les informations requises en tant que paramètres de la chaîne d'interrogation au lieu d'utiliser l'en-tête HTTP Authorization
. Cette méthode est utile pour activer l'accès direct d'un navigateur tiers vers les données Amazon S3 privées sans rediriger la demande. L'idée est de créer une demande « pré-signée » et de l'encoder comme une URL récupérable par le navigateur d'un utilisateur final. De plus, vous pouvez limiter une demande pré-signée en spécifiant un délai d'expiration.
Pour de plus amples informations sur l'utilisation des paramètres de requête pour authentifier les demandes, veuillez consulter Authentification des demandes à l'aide des paramètres de requête (AWS Signature Version 4) dans la Référence API Amazon Simple Storage Service. Pour obtenir des exemples d'utilisation des kits SDK AWS pour générer des URL pré-signées, veuillez consulter Partage d'objets à l'aide d'URL présignées.
Création d'une signature
Voici un exemple de requête REST Amazon S3 authentifiée par la chaîne d'interrogation.
GET /photos/puppy.jpg ?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D HTTP/1.1 Host: awsexamplebucket1.s3.us-west-1.amazonaws.com Date: Mon, 26 Mar 2007 19:37:58 +0000
La méthode d'authentification d'une demande par chaîne d'interrogation n'exige aucun en-tête HTTP spécial. A la place, les éléments d'authentification requis sont spécifiés en tant que paramètres de la chaîne d'interrogation :
Nom du paramètre de la chaîne d'interrogation | Exemple de valeur | Description |
---|---|---|
AWSAccessKeyId |
AKIAIOSFODNN7EXAMPLE |
Votre ID de clé d’accès AWS. Il spécifie la clé d'accès secrète AWS utilisée pour signer la demande et, indirectement, l'identité du développeur qui effectue la demande. |
Expires |
1141889120 |
Le délai d'expiration de la signature, indiqué en nombre de secondes depuis l'époque (00:00:00 UTC le 1er janvier 1970). Passé ce délai (selon le serveur), toute demande reçue est rejetée. |
Signature |
vjbyPxybdZaNmGa%2ByT272YEAiv4%3D |
Le codage URL du codage Base64 du HMAC-SHA1 de. StringToSign |
La méthode d'authentification de la demande par chaîne d'interrogation diffère légèrement du paramètre de la demande Signature
et de l'élément StringToSign
. Voici une pseudo-grammaire qui illustre la construction de la méthode d'authentification de la demande par chaîne d'interrogation.
Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKey, UTF-8-Encoding-Of( StringToSign ) ) ) ); StringToSign = HTTP-VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedAmzHeaders + CanonicalizedResource;
YourSecretAccessKey
est l'ID de la clé d'accès secrète AWS qu'Amazon vous attribue lorsque vous vous inscrivez pour être un développeur Amazon Web Service. Notez la façon dont la Signature
est encodée comme URL pour pouvoir être insérée dans la chaîne d'interrogation. Notez également que dans l'élément StringToSign
, l'élément HTTP positionnel Date
a été remplacé par Expires
. Les CanonicalizedAmzHeaders
et la CanonicalizedResource
sont identiques.
Note
Dans la méthode d'authentification par chaîne d'interrogation, vous n'utilisez pas le Date
ou l'en-tête x-amz-date request
lors du calcul de l'élément StringToSign.
Authentification d'une demande par chaîne d'interrogation
Demande | StringToSign |
---|---|
|
|
Nous supposons que lorsqu'un navigateur effectue une demande GET, il ne fournit pas d'en-tête Content-MD5 ou Content-Type, et ne configure aucun en-tête x-amz-, ces parties de l'élément StringToSign
restent donc vides.
Utilisation de l'encodage en Base64
Les signatures de la demande HMAC doivent être encodées en Base64. L'encodage Base64 convertit la signature en une simple chaîne de caractères ASCII qui peut être attachée à la demande. Les caractères qui peuvent apparaître dans la chaîne de signature comme plus (+), barre oblique (/) et égal (=) doivent être encodés s'ils sont utilisés dans une URI. Par exemple, si le code d'authentification inclut un signe plus (+), utilisez %2B dans la demande. Pour une barre oblique, utilisez %2F et pour le signe égal, utilisez %3D.
Pour obtenir des exemples d'encodage en Base64, consultez les Amazon S3 Exemples d'authentification.