Vous avez déployé une Azure Function utilisant Docker en production, tout semble bon, mais lorsque vous essayez d'appeler votre point de terminaison de fonction, vous obtenez une erreur frustrante 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
Pendant ce temps, votre environnement de développement non-dockerisé fonctionne parfaitement avec exactement le même code et les mêmes clés. Que se passe-t-il ?
D'abord, j'ai vérifié tous les suspects habituels :
AuthorizationLevel.Function dans mon code.Application Insights a révélé quelque chose d'intéressant :
Request successfully matched the route with name 'MyFunction' and template 'api/MyFunction' Executing StatusCodeResult, setting HTTP status code 401
La requête atteignait la fonction et correspondait à la route, mais Azure renvoyait 401 avant même que le code ne s'exécute. Cela signifiait que le problème se situait au niveau de la couche d'authentification du runtime Azure Functions, pas dans mon code.
J'ai inspecté les variables d'environnement via la console Kudu (https://my-functions.scm.azurewebsites.net) et j'ai trouvé :
AzureWebJobsSecretStorageType = files WEBSITES_ENABLE_APP_SERVICE_STORAGE = false # JE PENSAIS QUE C'ÉTAIT LE PROBLÈME !
Voici ce qui se passait :
Azure Functions peut stocker les clés d'authentification de deux façons :
AzureWebJobsSecretStorageType = files)/home/data/Functions/secrets/AzureWebJobsSecretStorageType = blob)Lorsque vous définissez WEBSITES_ENABLE_APP_SERVICE_STORAGE = false (courant pour les conteneurs Docker sans état), Azure ne monte pas de stockage persistant sur votre conteneur.
Cela signifie :
Laissez-moi vérifier cela dans le conteneur :
# SSH dans le conteneur ou via Kudu ls -la /home/data/ # Résultat : Aucun fichier ou répertoire de ce type ls -la /azure-functions-host/Secrets/ #Résultat : Aucun fichier ou répertoire de ce type
Le répertoire des secrets n'existait pas car le stockage n'était pas monté !
Quand j'ai initialement essayé de résoudre ce problème en définissant WEBSITES_ENABLE_APP_SERVICE_STORAGE = true, l'authentification fonctionnait mais j'obtenais 404 Not Found à la place !
\ Pourquoi ? Parce que le montage du stockage persistant d'Azure à /home/site/wwwroot/ écrasait les fichiers d'application de mon conteneur Docker. Le répertoire monté n'avait que host.json mais pas de DLLs compilés (dans le conteneur docker, pas le conteneur hôte, il est très important de garder à l'esprit qu'il y a deux conteneurs ici : le conteneur hôte et le conteneur docker de l'application) donc le runtime Azure Functions ne trouve 0 fonctions à charger, donc quand une requête arrive, l'authentification fonctionne (clés dans le blob) mais la fonction n'est pas trouvée, donc nous obtenons 404. En bref, cette option permet à l'hôte de trouver les fichiers de clés de fonction (donc l'authentification fonctionne) mais perd les fonctions elles-mêmes. Nous ne pouvons pas l'utiliser et WEBSITES_ENABLE_APP_SERVICE_STORAGE doit être false.
La correction correcte pour les Azure Functions Dockerisées est d'utiliser le stockage de secrets basé sur blob :
Dans le Portail Azure :
AzureWebJobsSecretStorageTypeblobWEBSITES_ENABLE_APP_SERVICE_STORAGE est falseCliquez sur Sauvegarder, puis redémarrez l'application de fonction. Azure va automatiquement :
azure-webjobs-secrets dans votre compte de stockageAllez à Portal → Function App → Functions → [Votre Fonction] → Function Keys
Copiez la clé depuis le Portail (c'est la version décryptée).
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
Comprendre le Chiffrement des Clés
Lorsque vous vérifiez le stockage blob, vous verrez les clés stockées comme ceci :
{ "keys": [ { "name": "default", "value": "CfDJ8AAAAAAA...encrypted-value...", "encrypted": true } ] }
Important : Vous ne pouvez pas utiliser cette valeur chiffrée directement ! Azure automatiquement :
Obtenez toujours vos clés depuis l'interface utilisateur du Portail Azure, qui affiche la version déchiffrée.
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
\
# Configuration du stockage des secrets AzureWebJobsSecretStorageType = blob AzureWebJobsStorage = <your-storage-connection-string> # Configuration Docker WEBSITES_ENABLE_APP_SERVICE_STORAGE = false WEBSITE_RUN_FROM_PACKAGE = 0 # Runtime Functions FUNCTIONS_WORKER_RUNTIME = dotnet FUNCTIONS_EXTENSION_VERSION = ~4
Ce problème est spécifique à Docker + Azure Functions parce que :
Les applications de fonction non dockerisées n'ont pas ce problème car elles ont naturellement accès au système de fichiers d'App Service.
Problème : Les Azure Functions Dockerisées renvoient 401 lors de l'utilisation du stockage de secrets basé sur fichiers sans volumes montés.
Solution : Utilisez le stockage de secrets basé sur blob, qui est sans état et compatible avec Docker.
Paramètres Clés :
AzureWebJobsSecretStorageType = blob WEBSITES_ENABLE_APP_SERVICE_STORAGE = false
Cette configuration permet à votre conteneur Docker de rester sans état tout en accédant de manière sécurisée aux clés d'authentification depuis Azure Blob Storage.
Vous rencontrez un problème similaire ? N'hésitez pas à nous contacter dans les commentaires ci-dessous !


