教學課程:使用 Windows VM 系統指派的受控識別來存取 Azure 儲存體

Azure 資源的受控識別是 Microsoft Entra ID 的功能。 每個支援適用於 Azure 資源的受控識別 Azure 服務均受限於其本身的時間表。 開始之前,請務必檢閱 資源受控識別的可用性 狀態和 已知問題

本教學課程說明如何使用系統指派的受控識別,讓 Windows 虛擬機器 (VM) 存取 Azure 儲存體。 您將學習如何:

  • 在記憶體帳戶中建立 Blob 容器
  • 將 Windows VM 系統指派的受控識別存取權授與記憶體帳戶
  • 取得存取權,並用它來呼叫 Azure 儲存體

注意

Azure 儲存體 的 Microsoft Entra 驗證處於公開預覽狀態。

必要條件

啟用

啟用系統指派的受控識別是一鍵式體驗。 您可以在建立 VM 期間或在現有 VM 的屬性中啟用它。

此螢幕快照顯示虛擬機的 [系統指派] 索引標籤,您可以在其中開啟系統指派的狀態。

若要在新 VM 上啟用系統指派的受控識別:

  1. 登入 Azure 入口網站

  2. 建立已啟用系統指派身分識別的虛擬機

授予存取權

建立儲存體帳戶

在本節中,您會建立記憶體帳戶。

  1. 選取位於 Azure 入口網站 左上角的 [+ 建立資源] 按鈕。

  2. 選取 [儲存體],然後 儲存體 帳戶 - blob、檔案、數據表、佇列

  3. 在 [名稱]下,輸入記憶體帳戶的名稱。

  4. 部署模型帳戶種類應設定為 Resource Manager儲存體 (一般用途 v1)

  5. 確定訂用帳戶和資源群組符合您在上一個步驟中建立 VM 時所指定的訂用帳戶和資源群組

  6. 選取 建立

    顯示如何建立新記憶體帳戶的螢幕快照。

建立 Blob 容器並將檔案上傳至記憶體帳戶

檔案需要 Blob 記憶體,因此您必須建立用來儲存檔案的 Blob 容器。 接著,您會將檔案上傳至新記憶體帳戶中的 Blob 容器。

  1. 流覽回新建立的記憶體帳戶。

  2. 在 [Blob 服務] 底下,選取 [容器]。

  3. 選取 頁面頂端的 [+ 容器 ]。

  4. [新增容器] 下,輸入容器的名稱,然後在 [公用存取層級] 下保留預設值。

    顯示如何建立記憶體容器的螢幕快照。

  5. 使用您選擇的編輯器,在本機計算機上建立標題為 hello world.txt的 檔案。 開啟檔案並新增文字 (不含引號) “Hello world! :)"然後儲存它。

  6. 按兩下容器名稱,然後將檔案上傳至新建立的容器,然後按兩下 [上傳]

  7. 在 [上傳 Blob] 窗格的 [檔案] 底下,選取資料夾圖示,然後流覽至本機計算機上的檔案hello_world.txt,選取檔案,然後選取 [上傳]。 顯示文字檔上傳畫面的螢幕快照。

授予存取權

本節說明如何將 VM 存取權授與 Azure 儲存體 容器。 您可以使用 VM 的系統指派受控識別來擷取 Azure 記憶體 Blob 中的數據。

  1. 流覽回新建立的記憶體帳戶。

  2. 選取 [存取控制 (IAM)]。

  3. 選取 [新增 > 角色指派 ] 以開啟 [新增角色指派] 頁面。

  4. 指派下列角色。 如需詳細步驟,請參閱使用 Azure 入口網站指派 Azure 角色

    設定
    角色 儲存體 Blob 資料讀者
    存取權指派對象 受控識別
    系統指派 虛擬機器
    選取 <您的虛擬機>

    顯示新增角色指派頁面的螢幕快照。

存取數據

Azure 儲存體 原生支援 Microsoft Entra 驗證,因此可以直接接受使用受控識別取得的存取令牌。 此方法使用 Azure 儲存體 與 Microsoft Entra ID 的整合,而且與在 連接字串 上提供認證不同。

以下是開啟連線至 Azure 儲存體 的 .NET 程式代碼範例。 此範例會使用存取令牌,然後讀取您稍早建立的檔案內容。 此程式代碼必須在 VM 上執行,才能存取 VM 的受控識別端點。 需要 .NET Framework 4.6 或更高版本,才能使用存取令牌方法。 請據以取代的值 <URI to blob file> 。 您可以瀏覽至您建立並上傳至 Blob 記憶體的檔案,並在 [概觀] 頁面底下複製 URL,以取得此值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Web.Script.Serialization;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

namespace StorageOAuthToken
{
    class Program
    {
        static void Main(string[] args)
        {
            //get token
            string accessToken = GetMSIToken("https://storage.azure.com/");

            //create token credential
            TokenCredential tokenCredential = new TokenCredential(accessToken);

            //create storage credentials
            StorageCredentials storageCredentials = new StorageCredentials(tokenCredential);

            Uri blobAddress = new Uri("<URI to blob file>");

            //create block blob using storage credentials
            CloudBlockBlob blob = new CloudBlockBlob(blobAddress, storageCredentials);

            //retrieve blob contents
            Console.WriteLine(blob.DownloadText());
            Console.ReadLine();
        }

        static string GetMSIToken(string resourceID)
        {
            string accessToken = string.Empty;
            // Build request to acquire MSI token
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=" + resourceID);
            request.Headers["Metadata"] = "true";
            request.Method = "GET";

            try
            {
                // Call /token endpoint
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                // Pipe response Stream to a StreamReader, and extract access token
                StreamReader streamResponse = new StreamReader(response.GetResponseStream());
                string stringResponse = streamResponse.ReadToEnd();
                JavaScriptSerializer j = new JavaScriptSerializer();
                Dictionary<string, string> list = (Dictionary<string, string>)j.Deserialize(stringResponse, typeof(Dictionary<string, string>));
                accessToken = list["access_token"];
                return accessToken;
            }
            catch (Exception e)
            {
                string errorText = String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
                return accessToken;
            }
        }
    }
}

回應包含檔案的內容:

Hello world! :)

停用

若要停用 VM 上的系統指派身分識別,請將系統指派身分識別的狀態設定為 [關閉]。

此螢幕快照顯示虛擬機的 [系統指派] 索引標籤,您可以在其中關閉系統指派的狀態。

下一步

在本教學課程中,您已瞭解如何啟用 Windows VM 系統指派的身分識別來存取 Azure 儲存體。 若要深入瞭解 Azure 儲存體,請參閱: