如何使用Microsoft.Azure.ResourceManager列出订阅?

时间:2016-04-18 09:06:58

标签: azure-active-directory azure-resource-manager

上下文

我的核心目标是在C#中编写Azure WebApps部署工具。这个过程大致是

  1. 用户登录
  2. 用户选择订阅
  3. 用户选择或创建资源组
  4. 用户为网络应用选择或创建存储空间
  5. 用户选择或创建网络服务计划
  6. 用户选择或创建网络应用
  7. 工具使用Kudu将网络应用上传到POST a zip
  8. 由于最后一步不能在门户网站中完成,我的想法是在GUI工具中完成所有工作。

    我开始使用Kudu的ARMClient.AuthenticationMicrosoft.Azure.ResourceManager 1.0.0-preview。但是,在创建存储帐户时,我收到权限错误(订阅未注册使用命名空间Microsoft.Storage ),因此我的计划B是在{{3}之后自己进行身份验证}}

    问题

    我已按照文档记录设置了应用程序,并使用其clientIdtenantId我能够登录并列出租户。但我无法列出任何订阅。 (注意,如果存在安全风险,请将clientIdtenantId部分省略。

            string clientId = "f62903b9-ELIDED";
            string tenantId = "47b6e6c3-ELIDED";
            const string redirectUri = "urn:ietf:wg:oauth:2.0:oob";
            const string baseAuthUri = "https://login.microsoftonline.com/";
            const string resource = "https://management.core.windows.net/";
    
            var ctx = new AuthenticationContext(baseAuthUri + tenantId);
            var authResult = ctx.AcquireToken(resource, clientId, new Uri(redirectUri), PromptBehavior.Auto);
            var token = new TokenCredentials(authResult.AccessToken);
            var subClient = new SubscriptionClient(token);
    
            var tenants = await subClient.Tenants.ListAsync();
            foreach (var tenant in tenants) Console.WriteLine(tenant.TenantId);
    
            var subs = await subClient.Subscriptions.ListAsync();
            foreach (var sub in subs) Console.WriteLine(sub.DisplayName);
    

    当我运行它时,它会提示我登录,并列出与我拥有或共同管理的订阅相对应的租户。但它并没有列出单个订阅。如果我将ID更改为常用(我认为正式为Powershell)值

            clientId = "1950a258-227b-4e31-a9cf-717495945fc2";
            tenantId = "common";
    

    然后它是一样的。

    为了获得订阅列表,我错过了哪些步骤?

2 个答案:

答案 0 :(得分:1)

你可以看一些事情......

1)您在创建存储帐户期间看到的错误可能是由于资源提供程序未注册用于订阅。任何RP都需要在使用前注册,一些客户端(Portal,PowerShell)会为你注册RP,所以你永远不会注意到它。请参阅:https://msdn.microsoft.com/en-us/library/azure/dn790548.aspx - 如果用户有足够的权限,您应该可以从代码中执行此操作。

2)您可能无法获得任何订阅,因为您的端点(management.core.windows.net)是Azure服务管理的端点,而不是Azure资源管理器(management.azure.com)。如果通过AzureRM和RBAC授予订阅访问权限,则旧的ASM apis将不会看到(即有权访问)这些订阅。

答案 1 :(得分:1)

您需要遍历租户,在租户中进行身份验证并获取每个租户的订阅列表。

以下代码将输出订阅,例如Get-AzureRmSubscription powershell cmdlet。

class Program
{
    private static string m_resource = "https://management.core.windows.net/";
    private static string m_clientId = "1950a258-227b-4e31-a9cf-717495945fc2"; // well-known client ID for Azure PowerShell
    private static string m_redirectURI = "urn:ietf:wg:oauth:2.0:oob"; // redirect URI for Azure PowerShell

    static void Main(string[] args)
    {
        try
        {
            var ctx = new AuthenticationContext("https://login.microsoftonline.com/common");
            // This will show the login window
            var mainAuthRes = ctx.AcquireToken(m_resource, m_clientId, new Uri(m_redirectURI), PromptBehavior.Always);
            var subscriptionCredentials = new TokenCloudCredentials(mainAuthRes.AccessToken);
            var cancelToken = new CancellationToken();
            using (var subscriptionClient = new SubscriptionClient(subscriptionCredentials))
            {
                var tenants = subscriptionClient.Tenants.ListAsync(cancelToken).Result;
                foreach (var tenantDescription in tenants.TenantIds)
                {
                    var tenantCtx = new AuthenticationContext("https://login.microsoftonline.com/" + tenantDescription.TenantId);
                    // This will NOT show the login window
                    var tenantAuthRes = tenantCtx.AcquireToken(
                        m_resource,
                        m_clientId,
                        new Uri(m_redirectURI),
                        PromptBehavior.Never,
                        new UserIdentifier(mainAuthRes.UserInfo.DisplayableId, UserIdentifierType.RequiredDisplayableId));
                    var tenantTokenCreds = new TokenCloudCredentials(tenantAuthRes.AccessToken);
                    using (var tenantSubscriptionClient = new SubscriptionClient(tenantTokenCreds))
                    {
                        var tenantSubscriptioins = tenantSubscriptionClient.Subscriptions.ListAsync(cancelToken).Result;
                        foreach (var sub in tenantSubscriptioins.Subscriptions)
                        {
                            Console.WriteLine($"SubscriptionName : {sub.DisplayName}");
                            Console.WriteLine($"SubscriptionId   : {sub.SubscriptionId}");
                            Console.WriteLine($"TenantId         : {tenantDescription.TenantId}");
                            Console.WriteLine($"State            : {sub.State}");
                            Console.WriteLine();
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        finally
        {
            Console.WriteLine("press something");
            Console.ReadLine();
        }
    }
}