Lorsqu'une passerelle ASM ou un proxy sidecar intercepte une requête et renvoie directement une réponse HTTP sans la transmettre au service en amont, le corps de la réponse par défaut est un message générique tel que not found ou RBAC: Access Denied. Le plug-in CustomLocalReply remplace ces réponses par défaut par des codes d'état, des en-têtes et un contenu de corps personnalisés. Vous pouvez ainsi rediriger les URL obsolètes, personnaliser les pages d'erreur avec votre charte graphique ou standardiser les formats d'erreur d'API dans l'ensemble de votre maillage.
Scénarios
| Objectif | Voir |
|---|---|
| Rediriger les URL obsolètes vers un nouvel emplacement | Rediriger une erreur 404 vers une autre URL |
| Renvoyer une page d'erreur HTML personnalisée plutôt qu'un texte brut | Renvoyer une page 403 personnalisée |
| Standardiser les réponses d'erreur d'API au format JSON | Renvoyer une réponse d'erreur JSON |
Génération des réponses locales
ASM génère une réponse locale (en contournant le service en amont) dans les situations suivantes :
| Déclencheur | Code d'état par défaut | Corps par défaut |
|---|---|---|
| Aucune règle de routage ne correspond à la requête | 404 |
not found |
| Une politique d'autorisation rejette la requête | 403 |
RBAC: Access Denied |
Un paramètre directResponse est configuré dans le VirtualService |
Défini par l'utilisateur | Défini par l'utilisateur |
Le plug-in CustomLocalReply intercepte ces réponses avant qu'elles n'atteignent le service en aval et applique vos substitutions.
Prérequis
Avant de commencer, assurez-vous d'avoir :
Déployé une passerelle d'entrée. Pour plus d'informations, consultez la rubrique Créer une passerelle d'entrée.
Déployé le service HTTPBin dans le cluster du plan de données. Consultez la documentation Déployer l'application HTTPBin
Référence de configuration
Champs de niveau supérieur
| Champ | Type | Obligatoire | Valeurs valides | Description |
|---|---|---|---|---|
patch_context |
String | Oui | GATEWAY, SIDECAR_INBOUND |
Contexte d'exécution. Définissez la valeur sur GATEWAY pour une passerelle ASM, ou sur SIDECAR_INBOUND pour un proxy sidecar. |
custom_error_pages |
CustomErrorPage[] | Oui | -- | Liste des substitutions de pages d'erreur. Chaque entrée associe un code d'état généré localement à une réponse personnalisée. |
Champs CustomErrorPage
| Champ | Type | Obligatoire | Par défaut | Description |
|---|---|---|---|---|
match_status_code |
Integer | Oui | -- | Code d'état généré localement à intercepter. Lorsque la passerelle ou le sidecar génère ce code, la substitution ci-dessous s'applique. |
return_status_code |
Integer | Oui | -- | Code d'état renvoyé au service en aval à la place du code correspondant. |
content_type |
String | Oui | -- | Valeur de l'en-tête de réponse content-type (par exemple, text/html; charset=UTF-8 ou application/json). |
headers |
Map[string]string | Non | null | En-têtes de réponse supplémentaires à inclure dans la réponse personnalisée. |
body |
String | Oui | -- | Corps de la réponse renvoyé au service en aval. |
Rediriger une erreur 404 vers une autre URL
Cet exemple intercepte la réponse 404 générée par une règle directResponse et la transforme en une redirection 301.
Étape 1 : Déployer un VirtualService avec une réponse directe
Appliquez le VirtualService suivant à votre instance ASM. Il configure la passerelle pour qu'elle renvoie un code d'état 404 avec le corps not found pour toutes les requêtes.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
namespace: default
spec:
gateways:
- httpbin-gateway
hosts:
- '*'
http:
- directResponse:
body:
string: not found
status: 404
Étape 2 : Activer le plug-in CustomLocalReply
Appliquez la configuration de plug-in suivante à la passerelle d'entrée ASM nommée ingressgateway. Elle identifie le code d'état 404 et le remplace par une redirection 301 vers https://www.aliyun.com.
patch_context: GATEWAY
custom_error_pages:
- match_status_code: 404
return_status_code: 301
headers:
location: 'https://www.aliyun.com'
content_type: text/html; charset=UTF-8
body: moved
Vérifier la redirection
Ouvrez un navigateur et accédez à l'adresse IP de la passerelle ASM. Le navigateur vous redirige vers https://www.aliyun.com, ce qui confirme que la configuration du plug-in est active.
Renvoyer une page 403 personnalisée
Cet exemple remplace le message par défaut RBAC: Access Denied par une page d'erreur HTML personnalisée lorsqu'une politique d'autorisation rejette une requête.
Appliquez la configuration de plug-in suivante à la passerelle d'entrée ASM nommée ingressgateway :
patch_context: GATEWAY
custom_error_pages:
- match_status_code: 403
return_status_code: 403
content_type: text/html; charset=UTF-8
body: |
<!DOCTYPE html>
<html>
<head><title>Access Denied</title></head>
<body>
<h1>403 - Access Denied</h1>
<p>You do not have permission to access this resource.
Contact your administrator if you believe this is an error.</p>
</body>
</html>
Lorsqu'une politique d'autorisation rejette une requête, la passerelle renvoie cette page HTML au lieu du message en texte brut RBAC: Access Denied.
Renvoyer une réponse d'erreur JSON
Cet exemple renvoie un corps d'erreur JSON structuré pour les réponses 404, ce qui s'avère utile pour les services d'API nécessitant un format d'erreur cohérent.
Appliquez la configuration de plug-in suivante à la passerelle d'entrée ASM nommée ingressgateway :
patch_context: GATEWAY
custom_error_pages:
- match_status_code: 404
return_status_code: 404
content_type: application/json
body: |
{
"error": {
"code": 404,
"message": "The requested resource was not found.",
"status": "NOT_FOUND"
}
}
Lorsque la passerelle génère une réponse 404, le service en aval reçoit un corps JSON avec une structure d'erreur standardisée au lieu du message en texte brut not found.
Plusieurs substitutions dans une seule configuration
Définissez plusieurs entrées dans custom_error_pages pour gérer différents codes d'état dans une seule configuration de plug-in. L'exemple suivant substitue à la fois les réponses 404 et 403 :
patch_context: GATEWAY
custom_error_pages:
- match_status_code: 404
return_status_code: 404
content_type: application/json
body: |
{
"error": {
"code": 404,
"message": "The requested resource was not found.",
"status": "NOT_FOUND"
}
}
- match_status_code: 403
return_status_code: 403
content_type: application/json
body: |
{
"error": {
"code": 403,
"message": "Access denied by authorization policy.",
"status": "FORBIDDEN"
}
}