Le plug-in hmac-auth génère des signatures infalsifiables pour les requêtes HTTP selon l'algorithme HMAC et les utilise pour l'authentification.
Type de plug-in
Authentification et autorisation.
Champs
Configuration d'authentification
|
Champ |
Type de données |
Obligatoire |
Valeur par défaut |
Description |
|
consumers |
array of object |
Oui |
- |
Les appelants du service, utilisés pour authentifier les requêtes. |
|
date_offset |
number |
Non |
- |
Décalage horaire maximal autorisé du client, en secondes. Le système analyse l'heure UTC du client à partir de l'en-tête de requête |
|
global_auth |
array of string |
Non (obligatoire uniquement pour les configurations au niveau de l'instance) |
- |
Uniquement au niveau de l'instance. S'il est défini sur true, l'authentification s'applique globalement. S'il est défini sur false, l'authentification s'applique uniquement aux noms de domaine et aux routes configurés. En l'absence de configuration, l'authentification s'applique globalement uniquement si aucun nom de domaine ni aucune route n'est configuré. |
Champs dans consumers :
|
Champ |
Type de données |
Obligatoire |
Valeur par défaut |
Description |
|
key |
string |
Oui |
- |
Clé d'accès du consommateur. |
|
secret |
string |
Oui |
- |
Secret utilisé pour générer la signature. |
|
name |
string |
Oui |
- |
Nom du consommateur. |
(Facultatif) Configuration d'autorisation
|
Champ |
Type de données |
Obligatoire |
Valeur par défaut |
Description |
|
allow |
array of string |
Non (obligatoire pour les configurations autres qu'au niveau de l'instance) |
- |
Configurable uniquement au niveau de la route ou du nom de domaine. Spécifie les consommateurs autorisés à accéder aux requêtes correspondantes pour un contrôle granulaire des permissions. |
Les configurations d'autorisation et d'authentification ne peuvent pas coexister dans la même règle.
Pour les requêtes authentifiées, l'en-tête
X-Mse-Consumerest ajouté pour identifier l'appelant.
Exemples
Configurer l'authentification globalement et l'autorisation pour les routes
L'exemple suivant active l'authentification hmac-auth pour des routes ou des domaines spécifiques. Le champ key doit être unique.
Appliquez les configurations de plug-in suivantes au niveau de l'instance :
global_auth: false
consumers:
- key: appKey-example-1
secret: appSecret-example-1
name: consumer-1
- key: appKey-example-2
secret: appSecret-example-2
name: consumer-2
Appliquez la configuration de plug-in suivante aux routes route-a et route-b :
allow:
- consumer1
Appliquez la configuration de plug-in suivante aux noms de domaine *.example.com et test.com :
allow:
- consumer2
Dans cet exemple, les routes
route-aetroute-bsont celles spécifiées lors de la création des routes de la passerelle. Si une requête client correspond à l'une des routes, l'appelant dont lenameestconsumer1est autorisé à accéder à la passerelle. Les autres appelants ne sont pas autorisés à y accéder.Dans cet exemple, les noms de domaine
*.example.comettest.comservent à faire correspondre les noms de domaine dans les requêtes. Si une requête client correspond à l'un des noms de domaine, l'appelant dont lenameestconsumer2est autorisé à accéder à la passerelle. Les autres appelants ne sont pas autorisés à y accéder.
Activer le plug-in traffic-tag pour les passerelles
global_auth: true
consumers:
- key: appKey-example-1
secret: appSecret-example-1
name: consumer-1
- key: appKey-example-2
secret: appSecret-example-2
name: consumer-2
Mécanisme de signature
Préparatifs de configuration
Configurez les identifiants suivants pour générer et valider les signatures :
key : utilisé dans l'en-tête de requête
x-ca-key.secret : utilisé pour générer la signature de la requête.
Générer une signature sur le client
Processus
Le client génère une signature en suivant ces étapes :
Extrayez les données clés de la requête d'origine pour générer une chaîne de signature.
Chiffrez la chaîne de signature avec le
secretconfiguré pour produire la signature.Ajoutez tous les en-têtes liés à la signature à la requête HTTP d'origine.
Extraire une chaîne de signature
Le client extrait les données clés de la requête HTTP et les combine dans une chaîne de signature au format suivant :
HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters
Ces champs sont séparés par \n. Si le champ Headers est vide, \n n'est pas requis. Pour les autres champs vides, \n doit être conservé. La signature est sensible à la casse.
Règles d'extraction pour chaque champ :
HTTPMethod : méthode HTTP, telle que POST. Doit être en majuscules.
Accept : valeur de l'en-tête de requête Accept. Peut être vide. Nous vous recommandons de définir explicitement l'en-tête Accept, car certains clients HTTP utilisent par défaut
*/*, ce qui entraîne l'échec de la vérification de la signature.-
Content-MD5 : valeur de l'en-tête Content-MD5. Peut être vide. Calculé uniquement lorsque la requête contient un corps non formulaire. Exemple Java :
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8"))); Content-Type : valeur de l'en-tête Content-Type. Peut être vide.
Date : valeur de l'en-tête Date, utilisée pour la vérification du décalage horaire. Peut être vide si
date_offsetn'est pas configuré.-
Headers : en-têtes inclus dans la signature. Règles de concaténation :
-
Triez les clés d'en-tête par ordre alphabétique et concaténez-les comme suit :
HeaderKey1 + ":" + HeaderValue1 + "\n"\+ HeaderKey2 + ":" + HeaderValue2 + "\n"\+ ... HeaderKeyN + ":" + HeaderValueN + "\n" Si la valeur d'un en-tête est vide, utilisez HeaderKey + ":" + "\n" pour la signature. La clé et les deux-points (:) doivent être conservés.
Les clés d'en-tête utilisées pour la signature sont séparées par des virgules (,) et placées dans l'en-tête
X-Ca-Signature-Headers.Les en-têtes suivants ne peuvent pas être utilisés dans le calcul de la signature : X-Ca-Signature, X-Ca-Signature-Headers, Accept, Content-MD5, Content-Type et Date.
-
-
PathAndParameters : contient le chemin, les paramètres de requête et les paramètres de formulaire.
Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
Les clés des paramètres de requête et de formulaire sont triées par ordre alphabétique puis concaténées comme décrit ci-dessus.
Si les paramètres de requête et de formulaire sont vides, utilisez uniquement le chemin sans ajouter d'informations de signature.
Pour les paramètres de tableau ayant la même clé mais des valeurs différentes, seule la première valeur est utilisée pour le calcul de la signature.
Exemple d'extraction d'une chaîne de signature
Requête HTTP initiale :
POST /http2test/test?param1=test HTTP/1.1
host:api.alibabacloud.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789
Chaîne de signature générée :
POST
application/json; charset=utf-8
application/x-www-form-urlencoded; charset=utf-8
Wed, 09 May 2018 13:30:29 GMT+00:00
x-ca-key:203753385
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-signature-method:HmacSHA256
x-ca-timestamp:1525872629832
/http2test/test?param1=test&password=123456789&username=xiaoming
Calculer une signature
Après avoir généré la chaîne de signature, le client la chiffre et l'encode pour produire la signature finale.
Dans ce code, stringToSign est la chaîne de signature extraite, secret provient de la configuration du plug-in et sign est la signature finale.
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] secretBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = Base64.encodeBase64String(result);
La variable stringToSign est décodée en un tableau d'octets UTF-8, chiffrée avec l'algorithme HMAC, puis encodée en Base64 pour produire la signature.
Ajouter une signature
Incluez les en-têtes suivants dans les requêtes envoyées à Cloud-native API Gateway pour la vérification de la signature :
x-ca-key : AppKey. Obligatoire.
x-ca-signature-method : algorithme de signature. Facultatif. Valeurs valides : HmacSHA256 et HmacSHA1. Valeur par défaut : HmacSHA256.
x-ca-signature-headers : toutes les clés d'en-tête de signature, séparées par des virgules (,). Facultatif.
x-ca-signature : signature. Obligatoire.
Exemple de requête HTTP avec une signature :
POST /http2test/test?param1=test HTTP/1.1
host:api.alibabacloud.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-key:203753385
x-ca-signature-method:HmacSHA256
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
content-length:33
username=xiaoming&password=123456789
Vérifier la signature côté serveur
Processus
Le serveur vérifie la signature du client en suivant ces étapes :
Extrayez les données clés de la requête pour obtenir une chaîne de signature.
Lisez la
keyde la requête et recherchez lesecretcorrespondant.Chiffrez la chaîne de signature avec le
secretpour produire une signature.Comparez la signature côté serveur avec la signature côté client de la requête.
Dépanner les erreurs de signature
Lorsque la vérification de la signature échoue, le serveur renvoie la StringToSign côté serveur dans l'en-tête de réponse X-Ca-Error-Message. Comparez-la avec la StringToSign côté client pour identifier la divergence.
Si les deux valeurs correspondent, vérifiez l'AppSecret utilisé pour le calcul de la signature.
Les en-têtes HTTP ne prenant pas en charge les sauts de ligne, les sauts de ligne dans StringToSign sont remplacés par #.
X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json##X-Ca-Key:200000#X-Ca-Timestamp:1589458000000#/app/v1/config/keys?keys=TEST`
Codes d'erreur
|
Code d'état HTTP |
Message d'erreur |
Raison |
|
400 |
Invalid Signature. |
La signature dans x-ca-signature ne correspond pas à la signature calculée par le serveur. |
|
400 |
Invalid Content-MD5. |
L'en-tête de requête Content-MD5 n'est pas valide. |
|
400 |
Invalid Date. |
Le décalage horaire de l'en-tête de requête Date dépasse le date_offset configuré. |
|
401 |
Invalid Key. |
L'en-tête de requête x-ca-key est manquant ou non valide. |
|
401 |
Empty Signature. |
L'en-tête de requête x-ca-signature est vide. |
|
403 |
Unauthorized Consumer. |
L'appelant de la requête ne dispose pas des permissions d'accès. |
|
413 |
Request Body Too Large. |
Le corps de la requête dépasse 32 Mo. |
|
413 |
Payload Too Large. |
Le corps de la requête dépasse les DownstreamConnectionBufferLimits configurés pour la passerelle. Vous pouvez augmenter les DownstreamConnectionBufferLimits sur la page de configuration des paramètres. |
L'augmentation de DownstreamConnectionBufferLimits augmente considérablement l'utilisation de la mémoire de la passerelle. Faites preuve de prudence.