Configuración de Azure Static Web Apps

La configuración de Azure Static Web Apps se define en el archivo staticwebapp.config.json, que controla las siguientes opciones:

  • Enrutamiento
  • Authentication
  • Authorization
  • Reglas de reserva
  • Invalidación de respuestas HTTP
  • Definiciones de encabezados HTTP globales
  • Tipos MIME personalizados
  • Redes

Nota

El archivo routes.json que se usó anteriormente para configurar el enrutamiento está en desuso. Use staticwebapp.config.json como se describe en este artículo para configurar el enrutamiento y otras opciones para la aplicación web estática.

Este documento es sobre Azure Static Web Apps, que es un producto independiente de la característica de hospedaje de sitios web estáticos de Azure Storage.

Ubicación del archivo

La ubicación recomendada del archivo staticwebapp.config.jsen es la carpeta establecida como app_location en el archivo de flujo de trabajo. Sin embargo, el archivo puede colocarse en cualquier subcarpeta dentro del conjunto de carpetas como app_location.

Consulte el archivo de configuración de ejemplo para ver los detalles.

Importante

El archivo routes.json en desuso se omite si existe un archivo staticwebapp.config.json.

Rutas

Las reglas de rutas permiten definir el patrón de direcciones URL que proporcionan acceso a la aplicación en la web. Las rutas se definen como una matriz de reglas de enrutamiento. Consulte el archivo de configuración de ejemplo para ver cómo se usan.

  • Las reglas se definen en la matriz routes, aunque solo tenga una ruta.
  • Las reglas se ejecutan en el orden en que aparecen en la matriz routes.
  • La evaluación de la regla se detiene en la primera coincidencia, ya que las reglas de enrutamiento no están encadenadas.
  • Tiene control total sobre los nombres de los roles personalizados.

Los aspectos relacionados con el enrutamiento se superponen en buena parte a los conceptos de autenticación (identificación del usuario) y autorización (concesión de capacidades al usuario). Asegúrese de leer la guía de autenticación y autorización junto con este artículo.

El archivo predeterminado para el contenido estático es index.html.

Definición de rutas

Cada una se compone de un patrón de ruta, junto con una o varias de las propiedades de regla opcionales. Las reglas de ruta se definen en la matriz routes. Consulte el archivo de configuración de ejemplo para ver cómo se usan.

Propiedad de regla Obligatorio Valor predeterminado Comentario
route N/D Patrón de ruta solicitado por el autor de la llamada.
  • Los caracteres comodín se admiten al final de las rutas.
    • Por ejemplo, la ruta admin/* coincide con cualquier ruta que se encuentre en la ruta de acceso admin.
rewrite No N/D Define el archivo o la ruta de acceso que devuelve la solicitud.
  • Es mutuamente excluyente con las reglas redirect
  • Las reglas de reescritura no cambian la ubicación del explorador.
  • Los valores deben hacer referencia a la raíz de la aplicación.
redirect No N/D Define el destino de redireccionamiento del archivo o la ruta de acceso de una solicitud.
  • Es mutuamente excluyente con las reglas rewrite
  • Las reglas de redireccionamiento cambian la ubicación del explorador.
  • El código de respuesta predeterminado es 302 (redireccionamiento temporal), pero puede invalidarse con 301 (redirección permanente).
allowedRoles No anonymous Define una lista de nombres de rol necesarios para acceder a una ruta.
  • Los caracteres válidos incluyen a-z, A-Z, 0-9 y _.
  • El rol integrado, anonymous, se aplica a todos los usuarios sin autenticar.
  • El rol integrado, authenticated, se aplica a todos los usuarios que han iniciado sesión.
  • Los usuarios deben pertenecer al menos a un rol.
  • Los roles se evalúan según el operador OR.
    • Si un usuario tiene cualquiera de los roles enumerados, se le concede acceso.
  • Los usuarios individuales se asocian a los roles a través de invitaciones.
headers No N/D Conjunto de encabezados HTTP que se agregan a la respuesta.
  • Los encabezados específicos de la ruta invalidan los encabezados globalHeaders cuando el encabezado específico de la ruta es igual que el encabezado global de la respuesta.
  • Para quitar un encabezado, establezca el valor en una cadena vacía.
statusCode No 200, 301 o 302 para las redirecciones Código de estado HTTP de la respuesta.
methods No Todos los métodos Lista de los métodos de solicitud que coinciden con una ruta. Algunos de los métodos disponibles son: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE y PATCH.

Cada propiedad tiene un propósito específico en la canalización de solicitudes o respuestas.

Propósito Propiedades
Establecer correspondencias en las rutas route, methods
Proporcionar autorización después de encontrar la correspondencia de una ruta allowedRoles
Realizar los procesos correspondientes una vez que se cumple y se autoriza una regla rewrite (modifica la solicitud)

redirect, headers y statusCode (modifica la respuesta)

Protección de rutas mediante roles

Las rutas están protegidas mediante la adición de uno o varios nombres de rol a la matriz allowedRoles de una regla. Consulte el archivo de configuración de ejemplo para ver cómo se usan.

De forma predeterminada, todos los usuarios pertenecen al rol de anonymous integrado, y todos los usuarios que han iniciado sesión son miembros del rol authenticated. Opcionalmente, los usuarios están asociados a roles personalizados a través de invitaciones.

Por ejemplo, para restringir una ruta solo a los usuarios autenticados, agregue el rol authenticated integrado a la matriz allowedRoles.

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

Puede crear nuevos roles según sea necesario en la matriz allowedRoles. Para restringir una ruta exclusivamente a los administradores, puede definir un rol propio llamado administrator en la matriz allowedRoles.

{
  "route": "/admin",
  "allowedRoles": ["administrator"]
}
  • Tiene control total sobre los nombres de rol, ya que no hay ninguna lista que los roles deban seguir.
  • Los usuarios individuales se asocian a los roles a través de invitaciones.

Caracteres comodín

Las reglas de caracteres comodín coinciden con todas las solicitudes de un patrón de ruta, solo se admiten al final de una ruta de acceso y se pueden filtrar por extensión de archivo. Consulte el archivo de configuración de ejemplo para ver cómo se usan.

Por ejemplo, si desea implementar las rutas de una aplicación de calendario, puede reescribir todas las direcciones URL que se encuentran en la ruta de calendar para que proporcionen un único archivo.

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

El archivo calendar.html puede usar el enrutamiento del lado cliente para generar una vista diferente para las variantes de las direcciones URL, como /calendar/january/1, /calendar/2020 y /calendar/overview.

Puede filtrar las coincidencias con caracteres comodín por la extensión de archivo. Por ejemplo, si desea agregar una regla que solo coincida con los archivos HTML de una ruta de acceso determinada, puede crear la siguiente regla:

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

Para filtrar por varias extensiones de archivo, incluya las opciones entre llaves, tal y como se muestra en este ejemplo:

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

Algunos de los casos de uso de las rutas con caracteres comodín más frecuentes son:

  • Proporcionar un archivo específico para todo un patrón de rutas de acceso
  • Asignar distintos métodos HTTP a todo un patrón de rutas de acceso
  • Aplicar reglas de autenticación y autorización
  • Implementar reglas de almacenamiento en caché especializadas

Rutas de reserva

Las aplicaciones de una sola página suelen utilizar el enrutamiento del lado cliente. Estas reglas de enrutamiento del lado cliente actualizan la ubicación de la ventana del explorador sin realizar solicitudes al servidor. Si actualiza la página o va directamente a las direcciones URL generadas por las reglas de enrutamiento del lado cliente, necesitará una ruta de reserva en el lado servidor para proporcionar la página HTML adecuada (que normalmente será el archivo index.html de la aplicación del lado cliente).

Puede definir una regla de reserva agregando una sección navigationFallback. En el siguiente ejemplo se devuelve /index.html para todas las solicitudes de archivos estáticos que no coinciden con un archivo implementado.

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

Puede controlar qué solicitudes devuelven el archivo de reserva definiendo un filtro. En el siguiente ejemplo, las solicitudes de determinadas rutas en la carpeta /images y todos los archivos de la carpeta /css están excluidos de la devolución del archivo de reserva.

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

En la estructura de archivos siguiente, se pueden conseguir los resultados que se indican a continuación con esta regla.

├── images
│   ├── logo.png
│   ├── headshot.jpg
│   └── screenshot.gif
│
├── css
│   └── global.css
│
└── index.html
Enviar una solicitud a... devuelve... con el estado...
/about/ El archivo index.html 200
/images/logo.png El archivo de imágenes 200
/images/icon.svg El archivo /index.html, ya que la extensión de archivo svg no aparece en el filtro /images/*.{png,jpg,gif} 200
/images/unknown.png Error de archivo no encontrado 404
/css/unknown.css Error de archivo no encontrado 404
/css/global.css Archivo de hoja de estilos 200
Cualquier otro archivo que esté fuera de las carpetas /images o /css El archivo index.html 200

Importante

Si va a migrar desde el archivo routes.json en desuso, no incluya la ruta de reserva heredada ("route": "/*") en las reglas de enrutamiento.

Encabezados globales

En la sección globalHeaders se proporciona un conjunto con los encabezados HTTP que se aplican a cada respuesta, a menos que queden invalidados por una regla de encabezado de ruta. De lo contrario, se devuelve la unión de los dos encabezados de la ruta y los encabezados globales.

Consulte el archivo de configuración de ejemplo para ver cómo se usan.

Para quitar un encabezado, establezca el valor en una cadena vacía ("").

Algunos casos de uso comunes de los encabezados globales son:

  • Reglas de almacenamiento en caché personalizadas
  • Aplicación de directivas de seguridad
  • Configuración de la codificación

Invalidación de respuestas

En la sección responseOverrides, se puede definir una respuesta personalizada en lugar de que el servidor devuelva un código de error. Consulte el archivo de configuración de ejemplo para ver cómo se usan.

Los siguientes códigos HTTP se pueden reemplazar:

Código de estado Significado Causa posible
400 Solicitud incorrecta Vínculo de invitación no válido
401 No autorizado Solicitud a páginas restringidas mientras no se está autenticado
403 Prohibido
  • El usuario ha iniciado sesión, pero no tiene los roles necesarios para ver la página.
  • El usuario ha iniciado sesión, pero el entorno de ejecución no puede obtener los detalles del usuario a partir de sus notificaciones de identidad.
  • Hay demasiados usuarios que han iniciado sesión en el sitio con roles personalizados, por lo que el entorno de ejecución no puede iniciar la sesión del usuario.
404 No encontrado Archivo no encontrado

En la configuración del ejemplo siguiente, se muestra cómo invalidar un código de error.

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

Redes

La sección networking controla la configuración de red de su aplicación web estática. Para restringir el acceso a su aplicación, especifique una lista de bloques de direcciones IP permitidos en allowedIpRanges.

Nota

La configuración de red solo está disponible en el plan Estándar de Azure Static Web Apps.

Defina cada bloque de direcciones IPv4 en la notación Enrutamiento de interdominios sin clases (CIDR). Para más información acerca de la notación CIDR, consulte Enrutamiento de interdominios sin clases. Cada bloque de direcciones IPv4 puede indicar un espacio de direcciones público o privado. Si solo desea permitir el acceso desde una sola dirección IP, puede usar el bloque CIDR /32.

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

Cuando se especifican uno o más bloques de direcciones IP, a las solicitudes que se originan desde direcciones IP que no coinciden con un valor en allowedIpRanges se les deniega el acceso.

Además de los bloques de direcciones IP, también puede especificar etiquetas de servicio en la matriz allowedIpRanges para restringir el tráfico a determinados servicios de Azure.

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

Authentication

Puerta de enlace de reenvío

En la sección forwardingGateway se configura cómo se accede a una aplicación web estática desde una puerta de enlace de reenvío, como un CDN o Azure Front Door.

Nota

La configuración de la puerta de enlace de reenvío solo está disponible en el plan estándar de Azure Static Web Apps.

Hosts reenviados permitidos

La lista allowedForwardedHosts especifica qué nombres de host se aceptan en el encabezado X-Forwarded-Host. Si un dominio que coincide está en la lista, Static Web Apps usa el valor X-Forwarded-Host al construir direcciones URL de redireccionamiento, después de realizar un inicio de sesión correcto.

Para que Static Web Apps funcione correctamente detrás de una puerta de enlace de reenvío, la solicitud de la puerta de enlace debe incluir el nombre de host correcto en el encabezado X-Forwarded-Host y el mismo nombre de host debe aparecer enumerado en allowedForwardedHosts.

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

Si el encabezado X-Forwarded-Host no coincide con un valor de la lista, las solicitudes siguen siendo correctas, pero el encabezado no se usa en la respuesta.

Encabezados obligatorios

Los encabezados obligatorios son encabezados HTTP que se deben enviar con cada solicitud al sitio. Un uso de los encabezados necesarios es denegar el acceso a un sitio a menos que todos los encabezados necesarios estén presentes en cada solicitud.

Por ejemplo, la configuración siguiente muestra cómo puede agregar un identificador único para Azure Front Door que limite el acceso al sitio desde una instancia de Azure Front Door específica. Consulte el tutorial de configuración de Azure Front Door para obtener todos los detalles.

"forwardingGateway": {
  "requiredHeaders": {
    "X-Azure-FDID" : "692a448c-2b5d-4e4d-9fcc-2bc4a6e2335f"
  }
}
  • Los pares clave-valor pueden ser cualquier conjunto de cadenas arbitrarias.
  • Las claves no distinguen mayúsculas de minúsculas.
  • Los valores distinguen mayúsculas de minúsculas.

Archivos de configuración de ejemplo

{
  "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"
  }
}

Consulte los escenarios siguientes teniendo en cuenta la configuración anterior.

Enviar una solicitud a... el resultado es...
/profile Los usuarios autenticados reciban el archivo /profile/index.html. Los usuarios sin autenticar acceden automáticamente a /login.
/admin/ Se proporciona el archivo /admin/reports/index.html a los usuarios autenticados con el rol administrator. Los usuarios autenticados que no tienen el rol administrator reciben un error403.1 Los usuarios sin autenticar acceden automáticamente a /login.
/logo.png Proporciona a la imagen una regla de caché personalizada en la que la antigüedad máxima es un poco superior a 182 días (15 770 000 segundos).
/api/admin Las solicitudes GET de los usuarios autenticados con el rol registeredusers se envían a la API. Los usuarios autenticados que no tienen el rol registeredusers y los que no se han autenticado reciben un error 401.

Las solicitudes POST, PUT, PATCH y DELETE de los usuarios autenticados con el rol administrator se envían a la API. Los usuarios autenticados que no tienen el rol administrator y los que no se han autenticado reciben un error 401.
/customers/contoso Los usuarios autenticados que pertenecen a los roles Administrador o customers_contoso reciben el archivo /customers/contoso/index.html. Los usuarios autenticados que no tienen los roles Administrador o customers_contoso reciben un error 4031. Los usuarios sin autenticar acceden automáticamente a /login.
/login Se pide a los usuarios sin autenticar que lo hagan con GitHub.
/.auth/login/twitter Como la autorización con Twitter está deshabilitada por la regla de ruta, se devuelve el error 404, que vuelve a proporcionar el archivo /index.html con el código de estado 200.
/logout Se cierra la sesión de los usuarios con cualquier proveedor de autenticación.
/calendar/2021/01 El explorador proporciona el archivo /calendar.html.
/specials El explorador accede de forma automática y permanente a /deals.
/data.json El archivo se proporciona con el tipo MIME text/json.
/about o cualquier carpeta que coincida con los patrones de enrutamiento del lado cliente El archivo /index.html se proporciona con el código de estado 200.
Archivo que no existe en la carpeta /images/ Error 404.

1 Puede proporcionar una página de error personalizada utilizando una regla de invalidación de respuestas.

Restricciones

El archivo staticwebapps.config.json tiene las siguientes restricciones.

  • El tamaño máximo del archivo es 100 KB.
  • Hay 50 roles distintos como máximo.

Consulte el artículo sobre cuotas para conocer las restricciones y limitaciones generales.

Pasos siguientes