Как программно перечислить подписки и клиентов Azure?

Как программно перечислить подписки и клиентов Azure? Это связано с моим предыдущим вопросом Login-AzureRmAccount (и связанным) эквиваленты в .NET Azure SDK.

В основном я пытаюсь воспроизвести поведение Login-AzureRmAccount и Get-AzureRmSubscription на рабочем столе или в консольном приложении. До сих пор я понял, что MSAL, похоже, всегда требует идентификатора клиента и идентификатор арендатора, поэтому должна быть какая-то другая библиотека, из которой можно их получить. После этого я хотел бы перейти к созданию принципала службы программно с использованием самой последней библиотеки, но я полагаю, что это предмет дальнейшего исследования (и вопросов, если необходимо).


person Veksi    schedule 24.06.2017    source источник


Ответы (1)


Фактически, Login-AzureRmAccount и Get-AzureRmSubscription используют приложение Microsoft Azure PowerShell для управления ресурсом Azure через REST API-интерфейсы Resource Manager.

Чтобы смоделировать те же операции с использованием REST, что и команды PowersShell, мы также можем использовать это приложение. Однако, поскольку это приложение зарегистрировано на портале Azure (а не в приложении v2.0), мы не можем получить токен с помощью этого приложения через MSAL. Нам нужно использовать Adal вместо MSAL.

Вот пример кода для вывода списка подписок с использованием учетной записи администратора через Microsoft.WindowsAzure.Management используя это приложение для справки:

public static void ListSubscriptions()
{
     string authority = "https://login.microsoftonline.com/common";
     string resource = "https://management.core.windows.net/";
     string clientId = "1950a258-227b-4e31-a9cf-717495945fc2";
    Uri redirectUri = new Uri("urn:ietf:wg:oauth:2.0:oob");
    AuthenticationContext authContext = new AuthenticationContext(authority);
    var access_token = authContext.AcquireTokenAsync(resource, clientId, redirectUri, new PlatformParameters (PromptBehavior.Auto)).Result.AccessToken;

    var tokenCred = new Microsoft.Azure.TokenCloudCredentials(access_token);
    var subscriptionClient = new SubscriptionClient(tokenCred);
    foreach (var subscription in subscriptionClient.Subscriptions.List())
    {
        Console.WriteLine(subscription.SubscriptionName);
    }
}

Обновлять:

string resource = "https://management.core.windows.net/";
string clientId = "1950a258-227b-4e31-a9cf-717495945fc2";
string userName = "";
string password = "";

HttpClient client = new HttpClient();
string tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/token";
var body = $"resource={resource}&client_id={clientId}&grant_type=password&username={userName}&password={password}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");

var result = client.PostAsync(tokenEndpoint, stringContent).ContinueWith<string>((response) =>
{
    return response.Result.Content.ReadAsStringAsync().Result;
}).Result;

JObject jobject = JObject.Parse(result);
var token = jobject["access_token"].Value<string>();

client.DefaultRequestHeaders.Add("Authorization", $"bearer {token}");
var subcriptions = client.GetStringAsync("https://management.azure.com/subscriptions?api-version=2014-04-01-preview").Result;

Console.WriteLine(subcriptions);
person Fei Xue - MSFT    schedule 26.06.2017
comment
Странный. Я устанавливаю пакет NuGet Microsoft.IdentityModel.Clients.ActiveDirectory 3.14.0, и если я сделаюvar access_token = authContext.AcquireTokenAsync(resource, clientId, redirectUri, new Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters(PromptBehavior.Auto)).Result;, такого класса не будет. Если я исключу PromptBehavior.Auto, я получу NotImplementedException. Хотя я вижу, что здесь использовалось и в другом месте. Это будет от Microsoft.WindowsAzure.Management? - person Veksi; 27.06.2017
comment
Возможно, у меня есть консольное приложение .NET Core, и в нем могут отсутствовать некоторые конструкторы. Я исследую это дальше примерно через 12 часов, но, возможно, что касается приведенного вами примера (и моих проблем с примерами кодов), виновником является .NET Core. - person Veksi; 27.06.2017
comment
И мы также можем отправить HTTP-запрос напрямую вместо использования Microsoft.WindowsAzure.Management. Вот ваш запрос: https://management.azure.com/subscriptions?api-version=2014-04-01-preview. В качестве временного решения этой проблемы можно использовать пароль владельца ресурса для получения токена доступа. Я также обновляю образец кода в посте. Однако у этого обходного пути есть некоторые ограничения. Например, пользователям необходимо сначала предоставить разрешение приложению. Это может предложить OP использовать команду Login-AzureRmAccount. И этот поток тоже не поддерживает MFA. - person Fei Xue - MSFT; 27.06.2017
comment
Это было очень полезно, я смогу добиться некоторого прогресса. Надеюсь, это поможет и другим в поисках ответов. Думаю, я подниму вопрос об этом в GH (или двух, другой во Fluent). - person Veksi; 29.06.2017