Azure active directory 如何使用Microsoft.Azure.ResourceManager列出订阅? 上下文

Azure active directory 如何使用Microsoft.Azure.ResourceManager列出订阅? 上下文,azure-active-directory,azure-resource-manager,Azure Active Directory,Azure Resource Manager,我的核心目标是用C#编写Azure WebApps部署工具。这一过程将是大致的 用户登录 用户选择订阅 用户选择或创建资源组 用户为web应用选择或创建存储 用户选择或创建web服务计划 用户选择或创建web应用程序 该工具使用Kudu将web应用上载到 因为最后一步不能在门户中完成,所以我的想法是在GUI工具中完成所有操作 我开始使用Kudu's和。但是,在创建存储帐户时,我会遇到一个权限错误(订阅未注册为使用名称空间Microsoft.storage),因此我的计划B是自己执行以下身份验证

我的核心目标是用C#编写Azure WebApps部署工具。这一过程将是大致的

  • 用户登录
  • 用户选择订阅
  • 用户选择或创建资源组
  • 用户为web应用选择或创建存储
  • 用户选择或创建web服务计划
  • 用户选择或创建web应用程序
  • 该工具使用Kudu将web应用上载到
  • 因为最后一步不能在门户中完成,所以我的想法是在GUI工具中完成所有操作

    我开始使用Kudu's和。但是,在创建存储帐户时,我会遇到一个权限错误(订阅未注册为使用名称空间Microsoft.storage),因此我的计划B是自己执行以下身份验证

    问题 我已经按照文档设置了一个应用程序,使用它的
    clientId
    tenantId
    我可以登录并列出租户。但我不能列出任何订阅。(注意,我已经部分删除了
    clientId
    tenantId
    ,以防全额提供它们存在安全风险)

    string clientId=“f62903b9省略”;
    字符串tenantId=“47b6e6c3省略”;
    常量字符串重定向URI=“urn:ietf:wg:oauth:2.0:oob”;
    常量字符串baseAuthUri=”https://login.microsoftonline.com/";
    常量字符串资源=”https://management.core.windows.net/";
    var ctx=newauthenticationcontext(baseAuthUri+tenantId);
    var authResult=ctx.AcquireToken(资源、clientId、新Uri(重定向Uri)、PromptBehavior.Auto);
    var-token=新的令牌凭证(authResult.AccessToken);
    var subClient=新的SubscriptionClient(令牌);
    var tenants=await subClient.tenants.ListAsync();
    foreach(租户中的var租户)控制台.WriteLine(租户.TenantId);
    var subs=await subClient.Subscriptions.ListAsync();
    foreach(subs中的var sub)Console.WriteLine(sub.DisplayName);
    
    当我运行它时,它会提示我登录,并列出与我拥有或共同管理的订阅相对应的租户。但它没有列出任何订阅。如果我将ID更改为常用(我认为正式用于Powershell)值

    那就一样了


    要获得我的订阅列表,我错过了什么步骤?

    您可以查看一些内容

    1) 您在创建存储帐户期间看到的错误可能是由于资源提供程序未注册以用于订阅。任何RP都需要在使用前注册,一些客户端(门户、PowerShell)会为您注册RP,因此您永远不会注意到它。请参阅:-如果用户有足够的烫发次数,您应该能够从代码中执行此操作


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

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

    以下代码将像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();
            }
        }
    }
    

    第二点是一个有趣的观察结果,但似乎没有解决任何问题(如果它解决了,我会感到惊讶,因为我直接拥有一个订阅)。然而,第一个似乎让我朝着目标前进。
    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();
            }
        }
    }