Azure VM 中使用身份識別來存取 Azure 服務

  • 96
  • 0

前言

在之前的文章 App Service 實做身份識別存取 KeyVault 中我們實做了使用身份識別在  App Service 中存取儲存體,而身份識別目前也在 Azure 很多服務都支援,其中一個就是常見的服務 VM,本文就來實做 VM 中的 IIS 執行的 ASP.NET 站台上使用身份識別存取儲存體。

實做

首先建立一台 Windows VM 並且安裝 IIS 和 .NET Runtime (假設要跑 .NET Core 的話需要另外安裝),然後在 Azure Portal 上面點選 VM 在左側選單找到身份識別,點選系統指派然後開啟並且儲存就可以為這一台 VM 建立身份識別的服務主體。

再來到 KeyVault 設定存取原則,這邊我只設定取得的權限,除非有必要寫入或做更多的管理,不然建議就設定最小使用權限,避免資安問題。

依序設定權限,在選擇主體的地方,應該可以搜尋到和 VM 名稱一樣的服務主體,選擇該主體即可。

而程式碼部分則是和之前 App Service 實做身份識別存取 KeyVault ,可以完全不需要修改就可以完成。

var secretClient = new SecretClient(new Uri("https://<vaultname>.vault.azure.net"),new DefaultAzureCredential());
var secret = await secretClient.GetSecretAsync("Test");
ViewData["Secret"] = secret.Value.Value;

在開發上,建議使用 DefaultAzureCredential,這樣可以在開發跟佈屬都使用相同的程式碼,不需要修改,程式會自動判斷可以使用的授權類型,假設想直接指定受控身份識別的類型則可以使用 ManagedIdentityCredential 並且帶入 VM 身份識別的 ClientId。

string userAssignedClientId = "<ID>";
var credential = new ManagedIdentityCredential(userAssignedClientId);

var secretClient = new SecretClient(new Uri("https://<vaultname>.vault.azure.net"), credential);
var secret = await secretClient.GetSecretAsync("Test");
ViewData["Secret"] = secret.Value.Value;

這邊要特別說明一下如何取得 ClientId,因為在前面畫面中的身份識別物件識別碼並非 ClientId,如果像我一開始很直覺得複製這一個值就會發現怎樣都會無法驗證成功的。

要取得真正的 ClientId 需要到 AAD 底下,點選企業應用程式,然後將類型選擇受控識別,就可以看到 VM 建立的受控識別,點選進去之後就可以取得正確的 ClientId 了。

如果設定上都沒有問題,應該就可以正確的在頁面上顯示我們取得的 Secret 了。

結論

微軟在 Azure 安全性上面做了很多不錯的設計,讓我們在開發的時候可以避免在程式碼或是 config 中寫死存取這些服務的驗證資訊,而是透過身份識別來作為授權的驗證,而在開發上也可以用同樣的程式碼來存取,不需要針對佈屬到環境的程式特別做修改,一律可以透過 DefaultAzureCredential 來存取,而本文介紹的都是使用 .NET 程式來作為範例,假設非 .NET 或是想要直接取得授權的 Access Token 則可以透過 Get 存取底下固定的網址,就可以在服務裡面取得 Access Token,在透過此  Token 直接打 Azure Rest API 來存取 Azure 相關服務。

http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F

其它有一些實做細節因為和 App Service 一樣,所以沒有特別再詳細說明,如有需要可以參考過去我寫的兩篇針對 App Service 實做身份識別的文章。

參考資料