Azure Многопользовательские приложения AD - Azure API управления ресурсами - Получение списка подписок для всех арендаторов, полученного с помощью API списка арендаторов - PullRequest
0 голосов
/ 04 августа 2020

Пытаясь получить все azure подписки для всех связанных пользователей-арендаторов, я использую образец решения azure, который я получил от GitHub, но решение не может получить всю подписку. Ссылка на образец решения . При циклическом прохождении каждого клиента я получаю сообщение об ошибке после вызова Azure Resource Management List Subscription API

Блок пробного кода ниже пропускает исключение для всех клиентов, кроме клиента в утверждениях

Не удалось получить токен в автоматическом режиме. Вызов метода AcquireToken

string tenantId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

, и исключение обрабатывается в блоке catch, где вместо authContext.AcquireToken вызывается authContext.AcquireTokenSilent

public static List<Subscription> GetUserSubscriptions(string organizationId)
        {
            List<Subscription> subscriptions = null;
            //string tenantId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
            string signedInUserUniqueName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value.Split('#')[ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value.Split('#').Length - 1];

            try
            {
                // Aquire Access Token to call Azure Resource Manager
                ClientCredential credential = new ClientCredential(ConfigurationManager.AppSettings["ida:ClientID"],
                    ConfigurationManager.AppSettings["ida:Password"]);
                // initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's EF DB
                AuthenticationContext authContext = new AuthenticationContext(
                    string.Format(ConfigurationManager.AppSettings["ida:Authority"], organizationId),
                    new ADALTokenCache(signedInUserUniqueName));
                AuthenticationResult result =
                    authContext.AcquireTokenSilent(
                        ConfigurationManager.AppSettings["ida:AzureResourceManagerIdentifier"], credential,
                        new UserIdentifier(signedInUserUniqueName, UserIdentifierType.RequiredDisplayableId));

                subscriptions = new List<Subscription>();

                // Get subscriptions to which the user has some kind of access
                string requestUrl = string.Format("{0}/subscriptions?api-version={1}",
                    ConfigurationManager.AppSettings["ida:AzureResourceManagerUrl"],
                    ConfigurationManager.AppSettings["ida:AzureResourceManagerAPIVersion"]);

                // Make the GET request
                HttpClient client = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = client.SendAsync(request).Result;

                if (response.IsSuccessStatusCode)
                {
                    string responseContent = response.Content.ReadAsStringAsync().Result;
                    dynamic subscriptionsResult = (Json.Decode(responseContent)).value;

                    foreach (dynamic subscription in subscriptionsResult)
                    {
                        subscriptions.Add(new Subscription()
                        {
                            Id = subscription.subscriptionId,
                            DisplayName = subscription.displayName,
                            OrganizationId = organizationId
                        });
                    }
                }
            }

ниже блока catch может получить токен после динамического изменения идентификатора клиента (идентификатора организации), но при использовании токена с REST API появляется следующая ошибка

{"error": {"code": "InvalidAuthenticationToken" , "message": "Полученный токен доступа недействителен: должно присутствовать хотя бы одно из утверждений 'puid', 'altsecid' или 'oid'. Если вы осуществляете доступ как приложение, убедитесь, что субъект-служба правильно создан в арендатор. "}}

catch (AdalException ex)
            {
                if (ex.ErrorCode == "failed_to_acquire_token_silently")
                {

                    ClientCredential credential = new ClientCredential(ConfigurationManager.AppSettings["ida:ClientID"],
          ConfigurationManager.AppSettings["ida:Password"]);
                    // initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's EF DB
                    AuthenticationContext authContext = new AuthenticationContext(
                        string.Format(ConfigurationManager.AppSettings["ida:Authority"], organizationId), new ADALTokenCache(signedInUserUniqueName));

                    //List<TokenCacheItem> items = authContext.TokenCache.ReadItems().ToList();
                    string resource = ConfigurationManager.AppSettings["ida:AzureResourceManagerIdentifier"];

                    AuthenticationResult result = authContext.AcquireToken(resource, credential);

                    subscriptions = new List<Subscription>();

                    // Get subscriptions to which the user has some kind of access
                    string requestUrl = string.Format("{0}/subscriptions?api-version={1}", ConfigurationManager.AppSettings["ida:AzureResourceManagerUrl"],
                        ConfigurationManager.AppSettings["ida:AzureResourceManagerAPIVersion"]);

                    // Make the GET request
                    HttpClient client = new HttpClient();
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                    HttpResponseMessage response = client.SendAsync(request).Result;

                    if (response.IsSuccessStatusCode)
                    {
                        string responseContent = response.Content.ReadAsStringAsync().Result;
                        var subscriptionsResult = (Json.Decode(responseContent)).value;

                        foreach (var subscription in subscriptionsResult)
                            subscriptions.Add(new Subscription()
                            {
                                Id = subscription.subscriptionId,
                                DisplayName = subscription.displayName,
                                OrganizationId = organizationId
                            });
                    }
                    else
                    {
                        string errMessage = response.Content.ReadAsStringAsync().Result;
                    }
                }             
            }

            return subscriptions;
        }```
...