在透過程式存取 Azure 資源的時候,基於安全性考量,通常是透過在 AAD 內建立應用程式註冊,透過註冊應用程式設定必要的權限來存取 Azure 資源,但是在使用 KeyVault 的時候就是希望有更高的安全性,會將金鑰或秘密存在服務內,但是這時候又會有一組應用程式註冊的 Secret 會需要被放到程式的參數內,那如果也想在開發階段也隱藏這一個金鑰的話就得使用微軟推出的身份識別功能,透過此功能來存取資源,可以在開發階段避免直接將應用程式註冊的 Id 和 Secret 交付給開發人員或是存放在設定檔內,本文就是介紹整個開發階段和部署到 Azure App Service 時候實做存取 Key Vault 內的 Secret。
前言
在透過程式存取 Azure 資源的時候,基於安全性考量,通常是透過在 AAD 內建立應用程式註冊,透過註冊應用程式設定必要的權限來存取 Azure 資源,但是在使用 KeyVault 的時候就是希望有更高的安全性,會將金鑰或秘密存在服務內,但是這時候又會有一組應用程式註冊的 Secret 會需要被放到程式的參數內,那如果也想在開發階段也隱藏這一個金鑰的話就得使用微軟推出的身份識別功能,透過此功能來存取資源,可以在開發階段避免直接將應用程式註冊的 Id 和 Secret 交付給開發人員或是存放在設定檔內,本文就是介紹整個開發階段和部署到 Azure App Service 時候實做存取 Key Vault 內的 Secret。
實做
建立 KeyValut
首先新增 KeyValut 服務

需要特別說明的設定是存取原則的設定部分,這些預設會帶入目前登入的帳號,並且設定所有的選項皆有權限,這邊可以針對後面要存取的開發者帳號設定僅可以存取秘密(Secret)的讀取權限即可,後面就可以在 Virual Studio 設定這一組帳號。

接下來在建立好的服務上建立一組 Test 的秘密 (Secret)


設定 Visual Studio
接下來針對開發環境設定 Azure 帳號,這邊設定的就是在前一個步驟存取原則內有設定的帳號。打開 Virual Studio 選單 [工具] → [設定] → [Azure 服務驗證],這邊設定好有權限的帳號即可。

實做程式
首先安裝 NuGet 套件 Azure.Identity 和 Azure.Security.KeyVault.Secrets

新增一個 .Net Core 專案,並且以 RazorPage 為範例

在 Index.cshtml.cs 內輸入底下程式碼,記得輸入自己剛剛建立的 KeyValut 存取網址。
var secretClient = new SecretClient(new Uri("https://<vaultname>.vault.azure.net"),new DefaultAzureCredential());
var secret = await secretClient.GetSecretAsync("Test");
ViewData["Secret"] = secret.Value.Value;
在 Index.cshtml 內顯示取得的 Secret
Secret:@ViewData["Secret"]
這時候執行程式測試就可以在頁面上面看到我們的 Secret 了。

然後我們直接把程式部署到 Azure App Service 上面執行,就會發現程式是無法存取 Secret 的,這是因為開發階段我們有設定是使用特定帳號有權限存取 KeyValut,但是 App Service 該如何設定這一組特定帳號?

App Service 設定身份識別
打開 App Service 設定找到身份識別,這邊就直接開啟系統指派的身份識別,然後就會自動幫我們建立一組身份識別,當我們 App Service 執行的時候就是會以這一個身份來執行程式。

這時候我們再到 KeyValut 新增存取原則,並且選擇剛剛系統幫我們建立的服務主體。


完成以上步驟之後我們部署到 App Service 的程式就可以正常存取 Secret 了。
結論
微軟針對 Azure 有越來越多安全性的設計,以及方便整合到自家的 Visual Studio 和 .NET Core,之前要做到在開發階段到部署都完全的隱藏這些 Secret 會需要花更多的功夫來隱藏這些資訊,現在可以方便的達到,對於多人開發上需要更安全的控管這些安全性或是開發和管理服務團隊分離,可以達到需要把這些資訊放在設定檔內,需要給特定人員開發時候,僅需要在 Azure 上面設定好相關權限即可,未來也可以更方便變更一些設定,比如說資料庫的連線字串等,都不需要再另外通開發人員調整設定。