Fungsi Azure yang di-Docker sering gagal dengan kesalahan 401 karena kontainer tidak dapat mengakses penyimpanan rahasia berbasis file. Solusinya adalah beralih ke penyimpanan rahasia berbasis blob, menjaga kontainer tetap stateless, dan membiarkan Azure menangani dekripsi kunci. Ini memulihkan autentikasi tanpa merusak build Anda.Fungsi Azure yang di-Docker sering gagal dengan kesalahan 401 karena kontainer tidak dapat mengakses penyimpanan rahasia berbasis file. Solusinya adalah beralih ke penyimpanan rahasia berbasis blob, menjaga kontainer tetap stateless, dan membiarkan Azure menangani dekripsi kunci. Ini memulihkan autentikasi tanpa merusak build Anda.

Cara Memperbaiki Error 401 Unauthorized pada Azure Functions yang Di-Dockerized

Masalah

Anda telah men-deploy Azure Function menggunakan Docker ke produksi, semuanya terlihat baik, tetapi ketika Anda mencoba memanggil endpoint fungsi Anda, Anda mendapatkan kesalahan 401 Unauthorized yang membuat frustrasi:

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

Sementara itu, lingkungan pengembangan non-dockerized Anda bekerja dengan sempurna dengan kode dan kunci yang sama persis. Apa yang terjadi?

Investigasi

Langkah 1: Singkirkan Hal yang Jelas

Pertama, saya memeriksa semua tersangka biasa:

  • Kunci fungsi sudah benar (disalin dari Portal → Functions → Function Keys)
  • Tidak ada Autentikasi App Service yang diaktifkan
  • Tidak ada pembatasan IP
  • CORS dikonfigurasi dengan benar
  • Level otorisasi diatur ke AuthorizationLevel.Function dalam kode saya.

Langkah 2: Periksa Log

Application Insights mengungkapkan sesuatu yang menarik:

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

Permintaan berhasil mencapai fungsi dan mencocokkan rute, tetapi Azure mengembalikan 401 sebelum kode bahkan dieksekusi. Ini berarti masalahnya ada pada lapisan autentikasi runtime Azure Functions, bukan dalam kode saya.

Langkah 3: Penemuan Kritis

Saya memeriksa variabel lingkungan melalui konsol Kudu (https://my-functions.scm.azurewebsites.net) dan menemukan:

AzureWebJobsSecretStorageType = files WEBSITES_ENABLE_APP_SERVICE_STORAGE = false # I THOUGHT THIS IS THE PROBLEM!

Akar Masalah

Inilah yang terjadi:

Bagaimana Azure Functions Menyimpan Kunci

Azure Functions dapat menyimpan kunci autentikasi dengan dua cara:

  1. Penyimpanan berbasis file (AzureWebJobsSecretStorageType = files)
  • Kunci disimpan sebagai file JSON di /home/data/Functions/secrets/
  • Memerlukan akses sistem file persisten
  • Default untuk aplikasi non-kontainer
  1. Penyimpanan berbasis blob (AzureWebJobsSecretStorageType = blob)
  • Kunci disimpan di Azure Blob Storage
  • Tidak ada ketergantungan sistem file
  • Direkomendasikan untuk kontainer Docker

Konflik Docker

Ketika Anda mengatur WEBSITES_ENABLE_APP_SERVICE_STORAGE = false (umum untuk kontainer Docker stateless), Azure tidak memasang penyimpanan persisten ke kontainer Anda.

Ini berarti:

  • Kunci fungsi Anda ada di penyimpanan Azure
  • Tetapi kontainer Anda tidak dapat mengaksesnya
  • Autentikasi selalu gagal dengan 401

Mari saya verifikasi ini di kontainer:

# SSH into container or via Kudu ls -la /home/data/ # Result: No such file or directory ls -la /azure-functions-host/Secrets/ #Result: No such file or directory

Direktori rahasia tidak ada karena penyimpanan tidak terpasang!

Masalah Sekunder

Ketika awalnya saya mencoba memperbaiki ini dengan mengatur WEBSITES_ENABLE_APP_SERVICE_STORAGE = true, autentikasi berhasil tetapi saya malah mendapatkan 404 Not Found!

\ Mengapa? Karena pemasangan penyimpanan persisten Azure di /home/site/wwwroot/ menimpa file aplikasi kontainer Docker saya. Direktori yang terpasang hanya memiliki host.json tetapi tidak ada DLL terkompilasi (dalam kontainer docker, bukan kontainer host, sangat penting untuk diingat bahwa ada dua kontainer di sini: kontainer host dan kontainer docker aplikasi) sehingga runtime Azure Functions menemukan 0 fungsi untuk dimuat, jadi ketika permintaan masuk, Autentikasi berhasil (kunci dalam blob) tetapi Fungsi tidak ditemukan sehingga kita mendapatkan 404. Singkatnya, opsi ini membuat host menemukan file kunci fungsi (sehingga autentikasi berhasil) tetapi kehilangan fungsi itu sendiri. Kita tidak bisa menggunakannya dan WEBSITES_ENABLE_APP_SERVICE_STORAGE harus false.

Solusi

Perbaikan yang benar untuk Azure Functions yang di-Dockerized adalah menggunakan penyimpanan rahasia berbasis blob:

Langkah 1: Ubah Tipe Penyimpanan Rahasia

Di Azure Portal:

  1. Buka Function App Anda
  2. Navigasi ke ConfigurationApplication Settings
  3. Temukan atau tambahkan: AzureWebJobsSecretStorageType
  4. Atur nilai ke: blob
  5. Pastikan: WEBSITES_ENABLE_APP_SERVICE_STORAGE adalah false

Langkah 2: Simpan dan Mulai Ulang

Klik Save, kemudian mulai ulang function app. Azure akan secara otomatis:

  • Membuat kontainer azure-webjobs-secrets di akun penyimpanan Anda
  • Memigrasikan kunci yang ada ke penyimpanan blob
  • Mengkonfigurasi runtime untuk membaca dari blob

Langkah 3: Dapatkan Kunci Anda

Buka Portal → Function App → Functions → [Fungsi Anda] → Function Keys

Salin kunci dari Portal (ini adalah versi yang didekripsi).

Langkah 4: Uji

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

Memahami Enkripsi Kunci

Ketika Anda memeriksa penyimpanan blob, Anda akan melihat kunci disimpan seperti ini:

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

Penting: Anda tidak dapat menggunakan nilai terenkripsi ini secara langsung! Azure secara otomatis:

  1. Menyimpan kunci terenkripsi di penyimpanan blob (untuk keamanan)
  2. Mendekripsi mereka saat runtime menggunakan kunci mesin
  3. Memvalidasi permintaan masuk terhadap nilai yang didekripsi

Selalu dapatkan kunci Anda dari UI Azure Portal, yang menampilkan versi yang didekripsi.

Referensi Konfigurasi Lengkap

Dockerfile (Contoh)

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

\

Pengaturan Aplikasi yang Diperlukan

# 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

Mengapa Ini Terjadi

Masalah ini khusus untuk Docker + Azure Functions karena:

  1. Kontainer Docker harus stateless dan tidak dapat diubah
  2. Rahasia berbasis file memerlukan penyimpanan persisten yang terpasang
  3. Pemasangan penyimpanan dapat menimpa file aplikasi dalam kontainer
  4. Solusinya adalah menggunakan penyimpanan blob, yang ramah stateless

Aplikasi fungsi non-dockerized tidak memiliki masalah ini karena mereka secara alami memiliki akses ke sistem file App Service.

Ringkasan

Masalah: Azure Functions yang di-Dockerized mengembalikan 401 saat menggunakan penyimpanan rahasia berbasis file tanpa volume yang terpasang.

Solusi: Gunakan penyimpanan rahasia berbasis blob, yang stateless dan ramah Docker.

Pengaturan Kunci:

AzureWebJobsSecretStorageType = blob WEBSITES_ENABLE_APP_SERVICE_STORAGE = false

Konfigurasi ini memungkinkan kontainer Docker Anda tetap stateless sambil tetap mengakses kunci autentikasi dengan aman dari Azure Blob Storage.


Memecahkan masalah serupa? Jangan ragu untuk menghubungi di komentar di bawah!

Penafian: Artikel yang diterbitkan ulang di situs web ini bersumber dari platform publik dan disediakan hanya sebagai informasi. Artikel tersebut belum tentu mencerminkan pandangan MEXC. Seluruh hak cipta tetap dimiliki oleh penulis aslinya. Jika Anda meyakini bahwa ada konten yang melanggar hak pihak ketiga, silakan hubungi [email protected] agar konten tersebut dihapus. MEXC tidak menjamin keakuratan, kelengkapan, atau keaktualan konten dan tidak bertanggung jawab atas tindakan apa pun yang dilakukan berdasarkan informasi yang diberikan. Konten tersebut bukan merupakan saran keuangan, hukum, atau profesional lainnya, juga tidak boleh dianggap sebagai rekomendasi atau dukungan oleh MEXC.