教程:使用 Windows VM 系统分配的托管标识访问 Azure 存储
Azure 资源的托管标识是 Microsoft Entra ID 的一项功能。 支持 Azure 资源的托管标识的每个 Azure 服务都受其自己的时间线限制。 在开始之前,请务必查看资源的托管标识的可用性状态以及已知问题。
本教程介绍了如何使用 Windows 虚拟机 (VM) 的系统分配的托管标识来访问 Azure 存储。 您将学习如何:
- 在存储帐户中创建 Blob 容器
- 向 Windows VM 的系统分配的托管标识授予对存储帐户的访问权限
- 获取访问令牌并使用它来调用 Azure 存储
注意
适用于 Azure 存储的 Microsoft Entra 身份验证当前处于公共预览版。
先决条件
- 如果不熟悉 Azure 资源功能的托管标识,请参阅此概述。
- 如果没有 Azure 帐户,请先注册试用版,然后再继续。
- 要执行所需的资源创建和角色管理,帐户在相应的范围(订阅或资源组)需要“所有者”权限。 如需角色分配方面的帮助,请参阅分配 Azure 角色以管理对 Azure 订阅资源的访问权限。
启用
启用系统分配的托管标识只需单击一次即可。 可以在创建 VM 的过程中或在现有 VM 的属性中启用它。
若要在新 VM 上启用系统分配的托管标识,请执行以下操作:
授予访问权限
创建存储帐户
在本部分中,创建一个存储帐户。
选择 Azure 门户左上角的“+ 创建资源”按钮。
单击“存储”,然后单击“存储帐户 - Blob、文件、表、队列”。
在“名称”下,输入存储帐户的名称。
“部署模型”和“帐户类型”应分别设置为“资源管理器”和“存储(常规用途 v1)”。
确保“订阅”和“资源组”与上一步中创建 VM 时指定的名称匹配。
选择创建。
创建 blob 容器,并将文件上传到存储帐户
文件需要 blob 存储,因此你需要创建用于存储文件的 blob 容器。 然后将文件上传到新存储帐户中的 blob 容器。
导航回新创建的存储帐户。
在“Blob 服务”下,选择“容器”。
选择页面顶部的“+ 容器”。
在“新建容器”下,输入容器的名称,并保留“公共访问级别”下的默认值。
使用你选择的编辑器,在本地计算机上创建一个标题为 hello world.txt 的文件。 打开该文件并添加文本“Hello world! :)”(不包括引号),然后保存该文件。
通过单击容器名称并单击“上传”,将该文件上传到新创建的容器。
在“上传 Blob”窗格中的“文件”下,选择文件夹图标并浏览到本地计算机上的文件 hello_world.txt,然后选择该文件并单击“上传”。
授予访问权限
本部分介绍如何授予 VM 访问 Azure 存储容器的权限。 可以使用 VM 的系统分配的托管标识检索 Azure 存储 blob 中的数据。
导航回新创建的存储帐户。
选择“访问控制 (IAM)”。
选择“添加”>“添加角色分配”,打开“添加角色分配”页面 。
分配以下角色。 有关详细步骤,请参阅使用 Azure 门户分配 Azure 角色。
设置 值 角色 存储 Blob 数据读取者 将访问权限分配到 托管标识 系统分配 虚拟机 Select <你的虚拟机>
访问数据
Azure 存储原生支持 Microsoft Entra 身份验证,因此可以直接接受使用托管标识获取的访问令牌。 此方法将 Azure 存储与 Microsoft Entra ID 集成结合使用,不同于在连接字符串中提供凭据。
以下 .NET 代码的示例是关于打开与 Azure 存储的连接。 该示例使用访问令牌,然后读取前面创建的文件的内容。 此代码必须在 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 存储,请参阅: