Las funciones de Azure en Docker a menudo fallan con errores 401 porque el contenedor no puede acceder al almacenamiento de secretos basado en archivos. La solución es cambiar al almacenamiento de secretos basado en blob, mantener el contenedor sin estado y dejar que Azure maneje la desencriptación de claves. Esto restaura la autenticación sin afectar tu compilación.Las funciones de Azure en Docker a menudo fallan con errores 401 porque el contenedor no puede acceder al almacenamiento de secretos basado en archivos. La solución es cambiar al almacenamiento de secretos basado en blob, mantener el contenedor sin estado y dejar que Azure maneje la desencriptación de claves. Esto restaura la autenticación sin afectar tu compilación.

Cómo solucionar errores 401 no autorizados en Azure Functions en contenedores Docker

2025/12/08 21:45
Lectura de 6 min
Si tienes comentarios o inquietudes sobre este contenido, comunícate con nosotros mediante crypto.news@mexc.com

El Problema

Has implementado una Azure Function usando Docker en producción, todo parece estar bien, pero cuando intentas llamar al endpoint de tu función, obtienes un frustrante error 401 Unauthorized:

curl -X POST \ "https://my-prod-functions.azurewebsites.net/api/MyFunction?code=my-function-key" \ -H "Content-Type: application/json" # Response: 401 Unauthorized

Mientras tanto, tu entorno de desarrollo sin Docker funciona perfectamente con exactamente el mismo código y claves. ¿Qué está pasando?

La Investigación

Paso 1: Descartar lo Obvio

Primero, revisé todos los sospechosos habituales:

  • Las claves de función eran correctas (copiadas desde Portal → Functions → Function Keys)
  • No hay autenticación de App Service habilitada
  • No hay restricciones de IP
  • CORS configurado correctamente
  • Nivel de autorización establecido como AuthorizationLevel.Function en mi código.

Paso 2: Revisar los Logs

Application Insights reveló algo interesante:

Request successfully matched the route with name 'MyFunction' and template 'api/MyFunction' Executing StatusCodeResult, setting HTTP status code 401

La solicitud estaba llegando a la función y coincidiendo con la ruta, pero Azure estaba devolviendo 401 antes de que el código se ejecutara. Esto significaba que el problema estaba en la capa de autenticación del runtime de Azure Functions, no en mi código.

Paso 3: El Descubrimiento Crítico

Inspeccioné las variables de entorno a través de la consola Kudu (https://my-functions.scm.azurewebsites.net) y encontré:

AzureWebJobsSecretStorageType = files WEBSITES_ENABLE_APP_SERVICE_STORAGE = false # ¡PENSÉ QUE ESTE ERA EL PROBLEMA!

La Causa Raíz

Esto es lo que estaba sucediendo:

Cómo Azure Functions Almacena las Claves

Azure Functions puede almacenar claves de autenticación de dos maneras:

  1. Almacenamiento basado en archivos (AzureWebJobsSecretStorageType = files)
  • Claves almacenadas como archivos JSON en /home/data/Functions/secrets/
  • Requiere acceso persistente al sistema de archivos
  • Predeterminado para aplicaciones no containerizadas
  1. Almacenamiento basado en blob (AzureWebJobsSecretStorageType = blob)
  • Claves almacenadas en Azure Blob Storage
  • Sin dependencia del sistema de archivos
  • Recomendado para contenedores Docker

El Conflicto con Docker

Cuando estableces WEBSITES_ENABLE_APP_SERVICE_STORAGE = false (común para contenedores Docker sin estado), Azure no monta almacenamiento persistente en tu contenedor.

Esto significa:

  • Tus claves de función existen en el almacenamiento de Azure
  • Pero tu contenedor no puede acceder a ellas
  • La autenticación siempre falla con 401

Permíteme verificar esto en el contenedor:

# SSH en el contenedor o vía Kudu ls -la /home/data/ # Resultado: No such file or directory ls -la /azure-functions-host/Secrets/ #Resultado: No such file or directory

¡El directorio de secretos no existía porque el almacenamiento no estaba montado!

El Problema Secundario

Cuando inicialmente intenté arreglar esto configurando WEBSITES_ENABLE_APP_SERVICE_STORAGE = true, la autenticación funcionó pero ¡obtuve 404 Not Found en su lugar!

\ ¿Por qué? Porque montar el almacenamiento persistente de Azure en /home/site/wwwroot/ sobrescribió los archivos de aplicación de mi contenedor Docker. El directorio montado solo tenía host.json pero no DLLs compilados (en el contenedor docker, no en el contenedor host, es muy importante tener en cuenta que hay dos contenedores aquí: el contenedor host y el contenedor docker de la aplicación), por lo que el runtime de Azure Functions encuentra 0 funciones para cargar, así que cuando llega una solicitud, la autenticación funciona (claves en blob) pero no se encuentra la función, por lo que obtenemos 404. En resumen, esta opción hace que el host encuentre los archivos de clave de función (por lo que la autenticación funciona) pero pierde las funciones en sí. No podemos usarlo y WEBSITES_ENABLE_APP_SERVICE_STORAGE debe ser false.

La Solución

La corrección correcta para Azure Functions en Docker es usar almacenamiento de secretos basado en blob:

Paso 1: Cambiar el Tipo de Almacenamiento de Secretos

En el Portal de Azure:

  1. Ve a tu Function App
  2. Navega a ConfiguraciónConfiguración de la aplicación
  3. Encuentra o añade: AzureWebJobsSecretStorageType
  4. Establece el valor como: blob
  5. Asegúrate de que: WEBSITES_ENABLE_APP_SERVICE_STORAGE sea false

Paso 2: Guardar y Reiniciar

Haz clic en Guardar, luego reinicia la function app. Azure automáticamente:

  • Creará un contenedor azure-webjobs-secrets en tu cuenta de almacenamiento
  • Migrará las claves existentes al almacenamiento blob
  • Configurará el runtime para leer desde blobs

Paso 3: Obtén tus Claves

Ve a Portal → Function App → Functions → [Tu Función] → Function Keys

Copia la clave desde el Portal (esta es la versión descifrada).

Paso 4: Prueba

curl -X POST \ "https://my-prod-functions.azurewebsites.net/api/MyFunction?code=<KEY_FROM_PORTAL>" \ -H "Content-Type: application/json" \ -d '{"test": "data"}' # Response: 200 OK

Entendiendo el Cifrado de Claves

Cuando revises el almacenamiento blob, verás las claves almacenadas así:

{ "keys": [ { "name": "default", "value": "CfDJ8AAAAAAA...encrypted-value...", "encrypted": true } ] }

Importante: ¡No puedes usar este valor cifrado directamente! Azure automáticamente:

  1. Almacena las claves cifradas en el almacenamiento blob (por seguridad)
  2. Las descifra en tiempo de ejecución usando claves de máquina
  3. Valida las solicitudes entrantes contra los valores descifrados

Siempre obtén tus claves desde la UI del Portal de Azure, que muestra la versión descifrada.

Referencia Completa de Configuración

Dockerfile (Ejemplo)

FROM mcr.microsoft.com/azure-functions/dotnet:4 AS base WORKDIR /home/site/wwwroot EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["MyFunction/MyFunction.csproj", "MyFunction/"] RUN dotnet restore "MyFunction/MyFunction.csproj" COPY . . WORKDIR "/src/MyFunction" RUN dotnet build "MyFunction.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "MyFunction.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /home/site/wwwroot COPY --from=publish /app/publish . ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ AzureFunctionsJobHost__Logging__Console__IsEnabled=true

\

Configuración de Aplicación Requerida

# Secret storage configuration AzureWebJobsSecretStorageType = blob AzureWebJobsStorage = <your-storage-connection-string> # Docker configuration WEBSITES_ENABLE_APP_SERVICE_STORAGE = false WEBSITE_RUN_FROM_PACKAGE = 0 # Functions runtime FUNCTIONS_WORKER_RUNTIME = dotnet FUNCTIONS_EXTENSION_VERSION = ~4

Por Qué Ocurre Esto

Este problema es específico de Docker + Azure Functions porque:

  1. Los contenedores Docker deben ser sin estado e inmutables
  2. Los secretos basados en archivos requieren almacenamiento persistente montado
  3. Montar almacenamiento puede sobrescribir archivos de aplicación containerizados
  4. La solución es usar almacenamiento blob, que es compatible con sistemas sin estado

Las aplicaciones de funciones no dockerizadas no tienen este problema porque naturalmente tienen acceso al sistema de archivos de App Service.

Resumen

Problema: Las Azure Functions dockerizadas devuelven 401 cuando usan almacenamiento de secretos basado en archivos sin volúmenes montados.

Solución: Usar almacenamiento de secretos basado en blob, que es sin estado y compatible con Docker.

Configuraciones Clave:

AzureWebJobsSecretStorageType = blob WEBSITES_ENABLE_APP_SERVICE_STORAGE = false

Esta configuración permite que tu contenedor Docker permanezca sin estado mientras accede de forma segura a las claves de autenticación desde Azure Blob Storage.


¿Solucionando un problema similar? ¡No dudes en contactar en los comentarios a continuación!

Aviso legal: Los artículos republicados en este sitio provienen de plataformas públicas y se ofrecen únicamente con fines informativos. No reflejan necesariamente la opinión de MEXC. Todos los derechos pertenecen a los autores originales. Si consideras que algún contenido infringe derechos de terceros, comunícate a la dirección crypto.news@mexc.com para solicitar su eliminación. MEXC no garantiza la exactitud, la integridad ni la actualidad del contenido y no se responsabiliza por acciones tomadas en función de la información proporcionada. El contenido no constituye asesoría financiera, legal ni profesional, ni debe interpretarse como recomendación o respaldo por parte de MEXC.