Ошибка при выполнении вызова API библиотеки управления Azure при аутентификации в активном каталоге Azure
Моя компания изучает отчетность по Azure. Мы только хотим, чтобы наши клиенты предоставили нам учетные данные только для чтения. Я провел некоторое исследование, и похоже, что Azure Active Directory делает именно это. Поэтому я пытаюсь пройти проверку подлинности с помощью приложения Azure Directory App только для чтения.
Чтобы начать, я следил за этим блогом об использовании API управления через Azure Active Directory.
https://msdn.microsoft.com/en-us/library/azure/dn722415.aspx
Помимо того, что подход показывает очень недружелюбно, он не работает = (
Я получаю эту ошибку после входа в систему в качестве глобального администратора:
«AADSTS90014: Тело запроса должно содержать следующий параметр:« client_secret или client_assertion ».»
Провел некоторое исследование и обнаружил, что этот стиль аутентификации был для нативных приложений, а НЕ веб-приложений (несмотря на то, что в блоге говорится иное ...) Так что я сделал твик. Мой GetAuthorizationHeader теперь выглядит так:
private static string GetAuthorizationHeader()
{
AuthenticationResult result = null;
var context = new AuthenticationContext("https://login.windows.net/" + ConfigurationManager.AppSettings["tenantId"]);
string clientId = ConfigurationManager.AppSettings["clientId"];
string clientSecret = ConfigurationManager.AppSettings["clientSecret"];
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
var thread = new Thread(() =>
{
result = context.AcquireToken(
"https://management.core.windows.net/",
clientCred);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Name = "AquireTokenThread";
thread.Start();
thread.Join();
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
Я могу получить токен доступа (yay). Но теперь, когда я пытаюсь использовать это с клиентом библиотеки управления Azure, я получаю эту ошибку:
«ForbiddenError: Серверу не удалось аутентифицировать запрос. Убедитесь, что сертификат действителен и связан с этой подпиской».
Я дважды проверил мои разрешения в моем приложении. Выглядело хорошо. Я попытался дать полный доступ ко всему, чтобы увидеть, изменит ли это что-нибудь.
Я дважды проверил свои tenantId, clientId и subscriptionId, все выглядело хорошо.
Я убедился, что используемая подписка указывает на AD, в котором находится мое приложение.
Я попытался сделать новый секретный ключ.
Я думаю, что это проблема:Однако в этом пользовательском интерфейсе я не могу выбрать какие-либо значения для этого свойства. Я не уверен, является ли это результатом ошибки или незавершенной функции. Я что-то здесь упускаю?
Спасибо
Вот мой полный код для справки:
class Program
{
static void Main(string[] args)
{
var token = GetAuthorizationHeader();
var credential = new TokenCloudCredentials(ConfigurationManager.AppSettings["subscriptionId"], token);
using (var computeClient = new ComputeManagementClient(credential))
{
var images = computeClient.VirtualMachineOSImages.List();
}
}
private static string GetAuthorizationHeader()
{
AuthenticationResult result = null;
var context = new AuthenticationContext("https://login.windows.net/" + ConfigurationManager.AppSettings["tenantId"]);
string clientId = ConfigurationManager.AppSettings["clientId"];
string clientSecret = ConfigurationManager.AppSettings["clientSecret"];
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
var thread = new Thread(() =>
{
result = context.AcquireToken(
"https://management.core.windows.net/",
clientCred);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Name = "AquireTokenThread";
thread.Start();
thread.Join();
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
}
РЕДАКТИРОВАТЬ: прогресс был достигнут. Как я уже говорил с Гауравом, мне нужно было отказаться от библиотеки управления Azure, поскольку на данный момент она, похоже, не поддерживает API менеджера ресурсов Azure (ARM)! Поэтому вместо этого я делал необработанные веб-запросы. И это работает как задумано. Если я удалю доступ к роли из своего приложения AD, мне будет отказано в доступе. Когда у меня есть это, я возвращаю данные.
В чем я не уверен, так это в том, чтобы мое приложение автоматически добавляло новые ресурсы.
Кроме того, есть ли способ перечислить группы ресурсов, которые доступны для моего приложения AD?
Новый код:
class Program
{
static void Main(string[] args)
{
var token = GetAuthorizationHeader();
string subscriptionId = ConfigurationManager.AppSettings["subscriptionId"];
string resourceGroupName = ConfigurationManager.AppSettings["resourceGroupName"];
var uriListMachines = string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Compute/virtualmachines?api-version=2015-05-01-preview", subscriptionId, resourceGroupName);
var t = WebRequest.Create(uriListMachines);
t.ContentType = "application/json";
t.Headers.Add("Authorization", "Bearer " + token);
var response = (HttpWebResponse)t.GetResponse();
string result = "";
using (var reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
//Original Attempt:
//var credential = new TokenCloudCredentials(ConfigurationManager.AppSettings["subscriptionId"], token);
//using (var client = CloudContext.Clients.CreateComputeManagementClient(credential))
//{
// var images = client.VirtualMachineVMImages.List();
//}
}
private static string GetAuthorizationHeader()
{
AuthenticationResult result = null;
var context = new AuthenticationContext("https://login.windows.net/" + ConfigurationManager.AppSettings["tenantId"]);
string clientId = ConfigurationManager.AppSettings["clientId"];
string clientSecret = ConfigurationManager.AppSettings["clientSecret"];
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
var thread = new Thread(() =>
{
result = context.AcquireToken(
"https://management.core.windows.net/",
clientCred);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Name = "AquireTokenThread";
thread.Start();
thread.Join();
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
}
РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ: я понял, что повесил трубку. Ресурсы, созданные на OLD портале, получат свою собственную группу ресурсов.
Из того, что я могу сказать, вы не можете добавить ресурс, сделанный на старом портале, в существующую группу ресурсов (boooo). Ресурсы, созданные на новом портале, смогут назначать ресурс существующей группе (то есть той, которая дает доступ к моему приложению AD).
Это такой беспорядок! Но, по крайней мере, я знаю, что происходит сейчас.