65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ARM API 和新的 Azure 门户访问 Azure 资源管理器虚拟机资源

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (4投票s)

2016年12月6日

CPOL

5分钟阅读

viewsIcon

8295

如何通过 Azure 资源管理器 (ARM) API 以编程方式访问 Azure 中的资源

在这篇文章中,我将解释如何使用 **Azure 资源管理器 (ARM) API** 以编程方式访问 **Azure** 中的 **资源**。为了说明这一点,我们将逐步完成一些步骤,在这些步骤中,我们将尝试使用注册到 **Azure Active Directory (AAD)** 的 **原生** 应用程序来访问托管在 **Azure** 中的 **虚拟机** 的详细信息。

为了本次演练,我在 Azure 订阅中创建了一个新的 VM。

Azure Subscription with VM

接下来,我们将在 Azure Active Directory 中创建一个 **原生应用程序**。

步骤 1:在 AAD 中创建原生应用程序

在 Azure 门户中,导航到 Azure Active Directory,然后单击 应用注册 部分。
接下来,单击顶部的 添加 选项。

Navigate to AAD App Registration

这将在右侧打开一个新窗格。

如下图所示,为应用程序提供一个 **名称**,在 **应用程序类型** 下拉菜单中选择 **原生** 应用程序选项,并在第三个输入选项中提供一个 **重定向 URI**。此 URL 不需要是实际的终结点,它只需要是一个有效的 URI。

New application details

单击底部的 **创建** 按钮,这样新的原生应用程序就会被创建。

Newly created application listed

接下来,我们将授权此应用程序访问 **Windows Azure 服务管理 API**。这将帮助我们稍后访问 ARM API。

步骤 2:授权原生应用程序访问 Azure 服务管理 API

单击新创建的应用程序(在此例中为 SKApp),然后单击 设置 选项。
这将在右侧打开一个窗格。单击 所需权限 选项,然后单击顶部的 添加 选项。

Native application delegate permissions option

现在,对于 **选择 API** 选项,请在右侧选择 **Windows Azure 服务管理 API** 选项。

Delegation API enumerations

选择后,按如下方式为应用程序授予访问此 API 的 **委托权限**:

Azure Service Mgmt API permission delegation

授予权限后,分配的权限列表将如下所示...

Delegated permission listing

步骤 3:为该原生应用程序创建密钥

现在我们将创建一个 **密钥** 并将其与此应用程序关联。
单击 **设置** 窗格中的 **密钥** 部分。

Open Keys blade

添加 **密钥描述** 并根据您的需要选择 **到期** 时间。

Key description and expiry

现在单击顶部的 **保存** 选项,就会生成一个密钥。
请 **安全地** 妥善保管此密钥,因为稍后我们尝试访问 ARM API 时将需要它。

Key generation

步骤 4:保存应用程序 ID 和目录 ID

现在我们已经生成并保存了一个 **密钥**,我们还需要保存 **原生应用程序** 的 **应用程序 ID** 和 Active Directory 实例的 **目录 ID**。

您将在原生应用程序详细信息窗格中找到 **应用程序 ID**。

Application ID

**目录 ID**,也称为 **租户 ID**,是 **AAD** 实例的 **唯一 ID**。
您可以在以下位置找到它:

Tenant ID

除了这些之外,我们还需要以下附加参数:

服务资源 ID

此 ID 的值为 https://management.core.windows.net/

OAuth 终结点

此 URL 用于授权,其值为 https://login.microsoftonline.com/<Directory ID>/oauth2/authorize
如上所示,授权 URL 需要 **目录 ID**。

至此,我们已经拥有了实现 **REST 客户端** 来消耗 **ARM API** 的所有详细信息。

但是,在执行此操作之前,我们需要执行一个额外的步骤,即在订阅上为我们的原生应用程序授予权限。

注意:这些权限可以在 **订阅**、**资源组** 或 **资源** 级别(在此例中为虚拟机级别)授予。

在 **订阅** 或 **资源组** 级别授予权限将 **继承** 给它们之下的所有资源。

步骤 5:在订阅级别授予原生应用程序权限

要授予权限,请钻取到我们要为此应用程序分配权限的相关订阅。

Grant Subscriptions rights

单击如上所示的 添加 选项,然后选择 读者 角色选项。

Select Reader role

完成后,通过在 添加用户 输入框中输入名称来选择我们之前创建的原生应用程序。
一旦应用程序显示出来,请选择它,然后单击下面的 选择 按钮。

Select application to assign role

就是这样!我们完成了。
现在我们可以继续使用 **REST 客户端** 来消耗 **ARM REST API**。

步骤 6:使用 REST 客户端和依赖参数消耗 ARM API

让我们创建一个简单的 **C#.NET 控制台** 应用程序来实现这一点。
您需要安装 Microsoft.IdentityModel.Clients.ActiveDirectory 的 NuGet 包。在撰写本文时,我使用的是 v3.13.8

我们将创建一个名为 AzureAD.cs 的类来对我们的用户进行身份验证并获取一个 **访问令牌**,该令牌稍后可用于调用基于 ARM 的 REST API。

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;

namespace AzureNewPortalResourceVMIntegration
{
    public class AzureAD
    {
        internal static string Authenticate(string authority, 
            string serviceResourceId, string clientId, string secretKey)
        {
            AuthenticationContext authContext = new AuthenticationContext(authority, true);
            AuthenticationResult authResult = null;

            try
            {
                authResult = authContext
                    .AcquireTokenAsync(serviceResourceId, 
                                new ClientCredential(clientId, secretKey)).Result;

                if (authResult != null)
                    Console.WriteLine("Auth Token: {0}", authResult.AccessToken);
                else
                    throw new Exception("Azure AD authentication failed.");

            }
            catch (AdalException adEx)
            {
                Console.WriteLine("Exception: {0}", adEx);
            }

            return authResult.AccessToken;
        }
    }
}

我们还需要一个类来使用此访问令牌发出 REST API 调用。我们将为此创建一个名为 AzureRestClient.cs 的类。

using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace AzureNewPortalResourceVMIntegration
{
    internal class AzureRestClient
    {
        internal static async Task<string> ExecuteRequest(string accessToken, string url)
        {
            string serviceBaseAddress = url;
            string responseMessage = null;

            HttpClient httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Authorization = 
                new AuthenticationHeaderValue("Bearer", accessToken);

            HttpResponseMessage response = 
                await httpClient.GetAsync(serviceBaseAddress);

            if (response.IsSuccessStatusCode)
            {
                responseMessage = await response.Content.ReadAsStringAsync();
                return responseMessage;
            }
            else
            {
                responseMessage = await response.Content.ReadAsStringAsync();

                if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    return "Access denied.";
                }
                return responseMessage;
            }
        }
    }
}

这样,我们就可以像这样获取我们的 VM SK-Lin-1 的详细信息了:

using System;

namespace AzureNewPortalResourceVMIntegration
{
    class Program
    {
        static void Main(string[] args)
        {
            string tenantId = "<Enter Directory Id>";
            string clientId = "<Enter Application Id>";
            string secretKey = "<Enter Secret Key>";
            string subscriptionId = "<Enter Subscription Id>";
            string resourceGroupName = "<Enter Resource group name>";
            string virtualMachineName = "<Enter Virtual Machine name>";

            string oauthUrl = "https://login.microsoftonline.com/{0}/oauth2/authorize";
            string serviceResourceId = "https://management.core.windows.net/";

            string authority = string.Format(oauthUrl, tenantId);

            string vmDetailsURL = 
            $"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/
            {resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{virtualMachineName}?
            api-version=2015-06-15";

            string accessToken = AzureAD.Authenticate
                    (authority, serviceResourceId, clientId, secretKey);

            if (accessToken != null)
            {
                AzureRestClient.ExecuteRequest(accessToken, vmDetailsURL)
                     .ContinueWith((task) =>
                     {
                         Console.WriteLine(task.Result);
                     });

            }
            Console.ReadLine();
        }
    }
}

有关用于获取 VM 详细信息的 **REST API** 的更多信息,请参阅 Azure 参考指南

获得响应后,您可以解析 **JSON 结果** 并从中提取相关数据。
您还可以从我的 github 仓库 下载源代码。

请探索 **Azure 参考文档**,其中列出了许多其他可用的 API。在所有情况下,代码都保持不变,只有 REST API URL 及其依赖参数会发生变化。

希望这对您有所帮助!

参考

文章 使用 ARM API 和新的 Azure 门户访问 Azure 资源管理器虚拟机资源 最初发布于 Sundeep Kamath 的博客

© . All rights reserved.