Error al realizar la llamada de la API de biblioteca de administración de Azure al autenticarse con el directorio activo de azul

Mi compañía está buscando informes sobre Azure. Solo queremos que nuestros clientes nos den credenciales de solo lectura para que las usemos. Hice algunas investigaciones y parece que Azure Active Directory hace precisamente eso. Así que estoy buscando autenticar usando una aplicación de directorio de Azure de solo lectura.

Para comenzar, estaba siguiendo este blog sobre el uso de la API de administración a través de Azure Active Directory.

https://msdn.microsoft.com/en-us/library/azure/dn722415.aspx

Aparte de que el enfoque de aproximación es muy antipático, no funciona = (

Recibo este error después de iniciar sesión como administrador global:

“AADSTS90014: el cuerpo de la solicitud debe contener el siguiente parámetro: ‘client_secret o client_assertion’.”

Hice algunas investigaciones y descubrí que este estilo de autenticación era para aplicaciones nativas y NO para aplicaciones web (a pesar de lo que la publicación del blog decía de otra manera …). Así que hice un ajuste. My GetAuthorizationHeader ahora se ve así:

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; } 

Puedo obtener el token de acceso (yay). Pero ahora, cuando trato de usar esto con el cliente de la biblioteca de gestión de Azure, aparece este error:

“ForbiddenError: el servidor no pudo autenticar la solicitud. Verifique que el certificado sea válido y esté asociado a esta suscripción”.

Revisé dos veces mis permisos en mi aplicación. Se veía bien. Traté de dar acceso completo a todo para ver si eso hubiera marcado la diferencia.

Comprobé dos veces mi ID de inquilino, ID de cliente y suscripción, todo se veía bien.

Me aseguré de que la suscripción que estoy utilizando apunta al AD en el que está mi aplicación.

Traté de hacer una nueva clave secreta.

Creo que este es el problema: enter image description here Sin embargo, en esta interfaz de usuario no puedo seleccionar ningún valor para esa propiedad. No estoy seguro si esto es el resultado de un error o una característica sin terminar. ¿Me estoy perdiendo de algo?

Gracias

Aquí está mi código completo para referencia:

 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; } } 

EDITAR: se ha avanzado. Cuando hablé con Gaurav, tuve que deshacerme de la Biblioteca de administración de Azure porque ahora mismo no parece ser compatible con la API de Azure Resource Manager (ARM). Entonces, en cambio, hice solicitudes web sin formato. Y funciona según lo previsto. Si elimino el acceso a las funciones de mi aplicación AD, se me niega el acceso. Cuando lo tengo, recupero los datos.

Una cosa de la que no estoy seguro es hacerlo para que mi aplicación agregue automáticamente nuevos recursos.

Además, ¿hay alguna manera de enumerar los grupos de recursos accesibles para mi aplicación AD?

Nuevo código:

  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; } } 

EDITAR EDITAR: Me di cuenta de que colgué. Los recursos creados en el portal OLD obtendrán su propio grupo de recursos.

Por lo que puedo decir, no puede agregar un recurso creado en el grupo de recursos existente del portal anterior (boooo). Los recursos creados en el nuevo portal podrán asignar el recurso a un grupo existente (también conocido como uno que da acceso a un rol a mi aplicación AD).

¡Esto es un desastre! Pero al menos sé lo que está pasando ahora.

Creo que estás en el camino correcto para saber por qué te encuentras con este problema.

Esto es lo que está pasando:

Básicamente, el permiso para ejecutar la Service Management API es un delegated permission and not an application permission . En otras palabras, la API se ejecuta en el contexto del usuario para el que se adquiere el token. Ahora está obteniendo este token para su aplicación (especificado por id / secreto del cliente). Sin embargo, su aplicación no tiene acceso a su suscripción de Azure porque el registro de usuario creado para esta aplicación en su Azure AD es de tipo Service Principal . Como este Director de Servicio no tiene acceso a su Suscripción Azure, está obteniendo este Forbidden Error (debo decir que el error es engañoso porque no está usando ningún certificado).

Hay algunas cosas que podrías hacer:

  1. Cambie a la API del Administrador de recursos de Azure (ARM): la API de ARM es la próxima generación de la API de administración de servicios (SM API) y Azure se está moviendo solo en esta dirección. Funciona exclusivamente con el token de Azure AD. Si es posible, utilícelo para administrar sus recursos de Azure (aunque debe tener en cuenta que a partir de hoy no todos los recursos de Azure se pueden administrar a través de la API de ARM). La forma en que lo hace es tomar su Director de Servicio y asignarlo a un rol particular utilizando el nuevo Azure Portal . Consulte este enlace para obtener más detalles al respecto: https://azure.microsoft.com/en-in/documentation/articles/resource-group-create-service-principal-portal/ .
  2. Use el certificado X509 : siempre puede usar la autorización basada en el certificado X509 para autorizar sus solicitudes SM API. Consulte este enlace para obtener más detalles al respecto: https://msdn.microsoft.com/en-us/library/azure/ee460782.aspx#bk_cert . La desventaja de este enfoque es que la aplicación (o cualquiera que tenga acceso a este certificado) obtendrá acceso completo a su suscripción a Azure y puede hacer todo lo que esté a su scope (incluida la eliminación de recursos).
  3. Adquiera token para un usuario en lugar de una aplicación : este es otro enfoque que puede tomar. Básicamente, solicite a sus usuarios que inicien sesión en Azure AD a través de su aplicación de consola y que adquieran el token para ese usuario. De nuevo, tenga en cuenta que este usuario debe ser un Co-Admin en su suscripción a Azure y tendrá pleno acceso a su suscripción a Azure, ya que con la API SM no existe el concepto de Role-based access control .