Configurer Azure Static Web Apps

La configuration d’Azure Static Web Apps est définie dans le fichier staticwebapp.config.json, qui contrôle les paramètres suivants :

  • Routage
  • Authentification
  • Autorisation
  • Règles de secours
  • Remplacement des réponses HTTP
  • Définitions globales d’en-tête HTTP
  • Types MIME personnalisés
  • Mise en réseau

Notes

routes.jssur qui a été précédemment utilisé pour configurer le routage est déconseillé. Utilisez staticwebapp.config.jssur tel que décrit dans cet article pour configurer le routage et d’autres paramètres pour votre application web statique.

Ce document concerne Azure Static Web Apps, qui est un produit autonome et distinct de la fonctionnalité d’hébergement de sites web statiques de Stockage Azure.

Emplacement du fichier

L’emplacement recommandé pour le fichier staticwebapp.config.json est le dossier défini comme app_location dans le fichier de workflow. Toutefois, le fichier peut être placé dans n’importe quel sous-dossier dans le dossier défini comme app_location.

Pour plus de détails, consultez l’exemple de fichier config.

Important

Le fichier routes.json déconseillé est ignoré si un fichier staticwebapp.config.json existe.

Itinéraires

Les règles de routage vous permettent de définir le modèle des URL qui permettent d’accéder à votre application sur le web. Les itinéraires sont définis sous forme de tableau de règles d’acheminement. Pour obtenir des exemples d’utilisation, consultez l’exemple de fichier config.

  • Les règles sont définies dans le tableau routes, même en présence d’un seul itinéraire.
  • Les règles sont exécutées dans l’ordre dans lequel elles apparaissent dans le tableau routes.
  • L’évaluation des règles s’arrête à la première correspondance : les règles d’acheminement ne sont pas enchaînées les unes aux autres.
  • Vous avez un contrôle total sur les noms de rôles personnalisés.

Les problèmes de routage chevauchent de manière significative les concepts d’authentification (identification de l’utilisateur) et d’autorisation (attribution de capacités à l’utilisateur). Lisez le Guide d’authentification et d’autorisation, ainsi que cet article.

Le fichier par défaut pour le contenu statique est le fichier index.html.

Définition des itinéraires

Chaque règle est composée d’un modèle d’itinéraire, ainsi que d’une ou plusieurs des propriétés facultatives de la règle. Les règles de routage sont définies dans le tableau routes. Pour obtenir des exemples d’utilisation, consultez l’exemple de fichier config.

Propriété de la règle Obligatoire Valeur par défaut Commentaire
route Oui n/a Modèle d’itinéraire demandé par l’appelant.
  • Les caractères génériques sont pris en charge à la fin des chemins d’accès d’itinéraire.
    • Par exemple, l’itinéraire admin/* correspond à n’importe quel itinéraire sous le chemin d’accès admin.
rewrite Non n/a Définit le fichier ou le chemin d’accès retourné par la demande.
  • S’exclut réciproquement d’une règle redirect.
  • Les règles de réécriture ne modifient pas l’emplacement du navigateur.
  • Les valeurs doivent être relatives à la racine de l’application.
redirect Non n/a Définit la destination de redirection du fichier ou du chemin d’accès pour une requête.
  • S’exclut réciproquement d’une règle rewrite.
  • Les règles de redirection modifient l’emplacement du navigateur.
  • Le code de réponse par défaut est un code 302 (redirection temporaire), mais vous pouvez le remplacer par un code 301 (redirection permanente).
allowedRoles Non anonyme Définit une liste de noms de rôles requis pour accéder à un itinéraire.
  • Les caractères valides sont a-z, A-Z, 0-9 et _.
  • Le rôle intégré anonymous s’applique à tous les utilisateurs non authentifiés.
  • Le rôle intégré authenticated s’applique à tous les utilisateurs connectés.
  • Les utilisateurs doivent appartenir à au moins un rôle.
  • Les rôles sont mis en correspondance sur une base OU.
    • Si un utilisateur se trouve dans l’un des rôles de la liste, l’accès est accordé.
  • Les utilisateurs individuels sont associés à des rôles par le biais des invitations.
headers Non n/a Ensemble d’en-têtes HTTP ajoutés à la réponse.
  • Les en-têtes spécifiques à l’itinéraire remplacent globalHeaders lorsque l’en-tête spécifique à l’itinéraire est le même que l’en-tête global dans la réponse.
  • Pour supprimer un en-tête, définissez la valeur sur une chaîne vide.
statusCode Non 200, 301 ou 302 pour les redirections Code d’état HTTP de la réponse.
methods Non Toutes les méthodes Liste des méthodes de demande qui correspondent à un itinéraire. Les méthodes disponibles sont notamment : GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE et PATCH.

Chaque propriété a un objectif spécifique dans le pipeline de demande/réponse.

Objectif Propriétés
Faire correspondre les itinéraires route, methods
Autoriser après la mise en correspondance d’un itinéraire allowedRoles
Traiter après la mise en correspondance et l’autorisation d’une règle rewrite (modifie la demande)

redirect, headers, statusCode (modifie la réponse)

Sécurisation des itinéraires avec des rôles

Les itinéraires sont sécurisés en y ajoutant un ou plusieurs noms de rôles dans le tableau allowedRoles de la règle. Pour obtenir des exemples d’utilisation, consultez l’exemple de fichier config.

Par défaut, chaque utilisateur appartient au rôle anonymous intégré et tous les utilisateurs connectés sont membres du rôle authenticated. Si vous le souhaitez, les utilisateurs sont associés à des rôles personnalisés via des invitations.

Par exemple, pour limiter un itinéraire aux seuls utilisateurs authentifiés, ajoutez le rôle authenticated intégré au groupe allowedRoles.

{
  "route": "/profile",
  "allowedRoles": ["authenticated"]
}

Vous pouvez créer des rôles en fonction des besoins dans le tableau allowedRoles. Pour restreindre un itinéraire aux seuls administrateurs, vous pouvez définir votre propre rôle, nommé administrator, dans le tableau allowedRoles.

{
  "route": "/admin",
  "allowedRoles": ["administrator"]
}
  • Vous avez un contrôle total sur les noms de rôles ; il n’existe pas de liste à laquelle vos rôles doivent adhérer.
  • Les utilisateurs individuels sont associés à des rôles par le biais des invitations.

Caractères génériques

Les règles de caractères génériques correspondent à toutes les demandes d’un modèle d’itinéraire, sont uniquement prises en charge à la fin d’un chemin d’accès et peuvent être filtrées par extension de fichier. Pour obtenir des exemples d’utilisation, consultez l’exemple de fichier config.

Par exemple, pour implémenter des itinéraires pour une application de calendrier, vous pouvez réécrire toutes les URL qui se trouvent sous l’itinéraire calendrier pour un seul fichier.

{
  "route": "/calendar/*",
  "rewrite": "/calendar.html"
}

Le fichier calendar.html peut ensuite utiliser le routage côté client pour offrir une vue différente des variantes d’URL, comme /calendar/january/1, /calendar/2020 et /calendar/overview.

Vous pouvez filtrer les correspondances de caractères génériques par extension de fichier. Par exemple, si vous souhaitez ajouter une règle qui correspond uniquement aux fichiers HTML dans un chemin donné, vous pouvez créer la règle suivante :

{
  "route": "/articles/*.html",
  "headers": {
    "Cache-Control": "public, max-age=604800, immutable"
  }
}

Pour filtrer sur plusieurs extensions de fichier, vous devez inclure les options entre accolades, comme illustré dans cet exemple :

{
  "route": "/images/thumbnails/*.{png,jpg,gif}",
  "headers": {
    "Cache-Control": "public, max-age=604800, immutable"
  }
}

Les cas d’usage courants pour les itinéraires de caractères génériques sont les suivants :

  • Servir un fichier spécifique pour un modèle de chemin complet
  • Mapper différentes méthodes HTTP à un modèle de chemin complet
  • Appliquer des règles d’authentification et d’autorisation
  • Implémenter des règles de mise en cache spécialisées

Itinéraires de secours

Les applications monopages s’appuient souvent sur le routage côté client. Ces règles d’acheminement côté client mettent à jour l’emplacement de la fenêtre du navigateur sans effectuer de demande au serveur. Si vous actualisez la page ou si vous accédez directement aux URL générées par les règles d’acheminement côté client, un itinéraire de secours côté serveur est requis pour servir la page HTML appropriée (qui est généralement le fichier index.html de votre application côté client).

Vous pouvez définir une règle de secours en ajoutant une section navigationFallback. L’exemple suivant renvoie /index.html pour toutes les demandes de fichier statique qui ne correspondent pas à un fichier déployé.

{
  "navigationFallback": {
    "rewrite": "/index.html"
  }
}

Vous pouvez contrôler les demandes qui renvoient le fichier de secours en définissant un filtre. Dans l’exemple suivant, les demandes concernant certains itinéraires du dossier /images et tous les fichiers du dossier /css sont exclues du renvoi du fichier de secours.

{
  "navigationFallback": {
    "rewrite": "/index.html",
    "exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
  }
}

Dans l’exemple de structure de fichiers ci-dessous, les résultats suivants sont possibles avec cette règle.

├── images
│   ├── logo.png
│   ├── headshot.jpg
│   └── screenshot.gif
│
├── css
│   └── global.css
│
└── index.html
Demande... renvoie… avec l’état…
/about/ Le fichier /index.html 200
/images/logo.png Le fichier image 200
/images/icon.svg Le fichier /index.html, puisque l’extension de fichier svg n’est pas listée dans le filtre /images/*.{png,jpg,gif} 200
/images/unknown.png Erreur Fichier introuvable 404
/css/unknown.css Erreur Fichier introuvable 404
/css/global.css Le fichier de feuille de style 200
Tout autre fichier en dehors des dossiers /images ou /css Le fichier /index.html 200

Important

Si vous effectuez une migration à partir du fichier routes.json déconseillé, n’incluez pas l’itinéraire de secours hérité ("route": "/*") dans les règles d’acheminement.

En-têtes globaux

La section globalHeaders fournit un ensemble d’en-têtes HTTP appliqués à chaque réponse, sauf s’ils sont remplacés par une règle d’en-tête d’itinéraire. Sinon, l’union des en-têtes de l’itinéraire et des en-têtes globaux est renvoyée.

Pour obtenir des exemples d’utilisation, consultez l’exemple de fichier config.

Pour supprimer un en-tête, définissez la valeur sur une chaîne vide ("").

Voici quelques cas d’usage courants pour les en-têtes globaux :

  • Règles de mise en cache personnalisées
  • Application de stratégies de sécurité
  • Paramètres de codage

Remplacement des réponses

La section responseOverrides permet de définir une réponse personnalisée lorsque le serveur retourne un code d’erreur. Pour obtenir des exemples d’utilisation, consultez l’exemple de fichier config.

Les codes HTTP suivants peuvent être remplacés :

Code d’état Signification Cause possible
400 Demande incorrecte Lien d’invitation non valide.
401 Non autorisé Demande de pages à accès restreint sans authentification.
403 Interdit
  • L’utilisateur est connecté, mais ne dispose pas des rôles nécessaires pour afficher la page.
  • L’utilisateur est connecté, mais le runtime ne peut pas récupérer les détails de l’utilisateur à partir de ses revendications d’identité.
  • Trop d’utilisateurs sont connectés au site avec des rôles personnalisés. Le runtime ne peut donc pas connecter l’utilisateur.
404 Introuvable Fichier introuvable

L’exemple de configuration suivant montre comment remplacer un code d’erreur.

{
  "responseOverrides": {
    "400": {
      "rewrite": "/invalid-invitation-error.html"
    },
    "401": {
      "statusCode": 302,
      "redirect": "/login"
    },
    "403": {
      "rewrite": "/custom-forbidden-page.html"
    },
    "404": {
      "rewrite": "/custom-404.html"
    }
  }
}

Mise en réseau

La section networking contrôle la configuration réseau de votre application web statique. Pour restreindre l’accès à votre application, spécifiez une liste de blocs d’adresses IP autorisés dans allowedIpRanges.

Notes

La configuration de la mise en réseau est uniquement disponible dans le plan Standard d’Azure Static Web Apps.

Définissez chaque bloc d’adresses IPv4 dans la notation CIDR (Classless InterDomain Routing). Pour plus d’informations sur la notation de routage CIDR, consultez Routage CIDR (Classless InterDomain Routing). Chaque bloc d’adresses IPv4 peut désigner un espace d’adressage public ou privé. Si vous souhaitez autoriser l’accès à partir d’une seule adresse IP, vous pouvez utiliser le bloc CIDR /32.

{
  "networking": {
    "allowedIpRanges": [
      "10.0.0.0/24",
      "100.0.0.0/32",
      "192.168.100.0/22"
    ]
  }
}

Lorsqu’un ou plusieurs blocs d’adresses IP sont spécifiés, les demandes provenant d’adresses IP qui ne correspondent à aucune valeur dans allowedIpRanges se voient refuser l’accès.

En plus des blocs d’adresses IP, vous pouvez également spécifier des étiquettes de service dans le tableau allowedIpRanges pour limiter le trafic vers certains services Azure.

"networking": {
  "allowedIpRanges": ["AzureFrontDoor.Backend"]
}

Authentification

Passerelle de transfert

La section forwardingGateway configure le mode d’accès à une application web statique à partir d’une passerelle de transfert, telle qu’un CDN ou une Azure Front Door.

Notes

La configuration de la passerelle de transfert est uniquement disponible dans le plan Standard d’Azure Static Web Apps.

Hôtes transférés autorisés

La liste allowedForwardedHosts spécifie les noms d’hôte à accepter dans l’en-tête X-Forwarded-Host. Si un domaine correspondant figure dans la liste, Static Web Apps utilise la valeur X-Forwarded-Host lors de la construction des URL de redirection, par exemple après une connexion réussie.

Pour que Static Web Apps fonctionne correctement derrière une passerelle de transfert, la demande de la passerelle doit inclure le nom d’hôte correct dans l'en-tête X-Forwarded-Host et le même nom d’hôte doit être indiqué dans allowedForwardedHosts.

"forwardingGateway": {
  "allowedForwardedHosts": [
    "example.org",
    "www.example.org",
    "staging.example.org"
  ]
}

Si l'en-tête X-Forwarded-Host ne correspond pas à une valeur de la liste, les demandes sont toujours exécutées, mais l’en-tête n’est pas utilisé dans la réponse.

En-têtes obligatoires

Les en-têtes requis sont des en-têtes HTTP qui doivent être envoyés avec chaque demande adressée à votre site. Une utilisation des en-têtes requis consiste à refuser l’accès à un site, sauf si tous les en-têtes requis sont présents dans chaque demande.

Par exemple, la configuration suivante montre comment vous pouvez ajouter un identificateur unique pour Azure Front Door qui limite l’accès à votre site à partir d’une instance Azure Front Door. Pour plus d’informations, consultez le didacticiel Configurer Azure Front Door .

"forwardingGateway": {
  "requiredHeaders": {
    "X-Azure-FDID" : "692a448c-2b5d-4e4d-9fcc-2bc4a6e2335f"
  }
}
  • Les paires clé/valeur peuvent être n’importe quel ensemble de chaînes arbitraires
  • Les clés sont insensibles à la casse
  • Les valeurs respectent la casse

Exemple de fichier de configuration

{
  "routes": [
    {
      "route": "/profile",
      "allowedRoles": ["authenticated"]
    },
    {
      "route": "/admin/*",
      "allowedRoles": ["administrator"]
    },
    {
      "route": "/images/*",
      "headers": {
        "cache-control": "must-revalidate, max-age=15770000"
      }
    },
    {
      "route": "/api/*",
      "methods": ["GET"],
      "allowedRoles": ["registeredusers"]
    },
    {
      "route": "/api/*",
      "methods": ["PUT", "POST", "PATCH", "DELETE"],
      "allowedRoles": ["administrator"]
    },
    {
      "route": "/api/*",
      "allowedRoles": ["authenticated"]
    },
    {
      "route": "/customers/contoso",
      "allowedRoles": ["administrator", "customers_contoso"]
    },
    {
      "route": "/login",
      "rewrite": "/.auth/login/github"
    },
    {
      "route": "/.auth/login/twitter",
      "statusCode": 404
    },
    {
      "route": "/logout",
      "redirect": "/.auth/logout"
    },
    {
      "route": "/calendar/*",
      "rewrite": "/calendar.html"
    },
    {
      "route": "/specials",
      "redirect": "/deals",
      "statusCode": 301
    }
  ],
  "navigationFallback": {
    "rewrite": "index.html",
    "exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
  },
  "responseOverrides": {
    "400": {
      "rewrite": "/invalid-invitation-error.html"
    },
    "401": {
      "redirect": "/login",
      "statusCode": 302
    },
    "403": {
      "rewrite": "/custom-forbidden-page.html"
    },
    "404": {
      "rewrite": "/404.html"
    }
  },
  "globalHeaders": {
    "content-security-policy": "default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'"
  },
  "mimeTypes": {
    ".json": "text/json"
  }
}

En fonction de la configuration ci-dessus, passez en revue les scénarios suivants.

Demande... a pour résultat…
/profile Les utilisateurs authentifiés reçoivent le fichier /profile/index.html. Les utilisateurs non authentifiés sont redirigés vers /login.
/admin/ Les utilisateurs authentifiés ayant le rôle administrator reçoivent le fichier /admin/index.html. Les utilisateurs authentifiés qui n’ont pas le rôle administrator reçoivent une erreur 4031. Les utilisateurs non authentifiés sont redirigés vers /login.
/logo.png Délivre l’image avec une règle de cache personnalisée dont l’âge maximal est un peu plus de 182 jours (15 770 000 secondes).
/api/admin Les demandes GET des utilisateurs authentifiés ayant le rôle registeredusers sont envoyées à l’API. Les utilisateurs authentifiés qui n’ont pas le rôle registeredusers et les utilisateurs non authentifiés reçoivent une erreur 401.

Les demandes POST, PUT, PATCH et DELETE des utilisateurs authentifiés ayant le rôle administrator sont envoyées à l’API. Les utilisateurs authentifiés qui n’ont pas le rôle administrator et les utilisateurs non authentifiés reçoivent une erreur 401.
/customers/contoso Les utilisateurs authentifiés qui appartiennent aux rôles administrator ou customers_contoso reçoivent le fichier /customers/contoso/index.html. Les utilisateurs authentifiés qui n’ont pas le rôle administrator ou customers_contoso reçoivent une erreur 403 1. Les utilisateurs non authentifiés sont redirigés vers /login.
/login Les utilisateurs non authentifiés sont invités à s’authentifier auprès de GitHub.
/.auth/login/twitter Comme l’autorisation avec Twitter est désactivée par la règle d’acheminement, une erreur 404 est renvoyée, ce qui revient à remettre /index.html avec un code d’état 200.
/logout Les utilisateurs sont déconnectés de tous les fournisseurs d’authentification.
/calendar/2021/01 Le navigateur reçoit le fichier /calendar.html.
/specials Le navigateur est redirigé de façon permanente vers /deals.
/data.json Le fichier remis avec le type MIME text/json.
/about, ou tout dossier qui correspond aux modèles de routage côté client Le fichier /index.html est remis avec un code d’état 200.
Un fichier inexistant dans le dossier /images/ Une erreur 404.

1 Vous pouvez fournir une page d’erreur personnalisée en utilisant une règle de remplacement de la réponse.

Restrictions

Les restrictions suivantes existent pour le fichier staticwebapp.config.json.

  • La taille maximale des fichiers est de 100 ko.
  • Maximum de 50 rôles distincts.

Consultez l’article sur les quotas pour connaître les restrictions et les limitations générales.

Étapes suivantes