¿Cómo hacer que HttpClient pase las credenciales junto con la solicitud?

Resuelto adrianbanks asked hace 12 años • 10 respuestas

Tengo una aplicación web (alojada en IIS) que se comunica con un servicio de Windows. El servicio de Windows utiliza la API web ASP.Net MVC (autohospedada) y, por lo tanto, se puede comunicar a través de http mediante JSON. La aplicación web está configurada para realizar suplantación, la idea es que el usuario que realiza la solicitud a la aplicación web debe ser el usuario que la aplicación web utiliza para realizar la solicitud al servicio. La estructura se ve así:

(El usuario resaltado en rojo es el usuario al que se hace referencia en los ejemplos siguientes).


La aplicación web realiza solicitudes al servicio de Windows mediante HttpClient:

var httpClient = new HttpClient(new HttpClientHandler() 
                      {
                          UseDefaultCredentials = true
                      });
httpClient.GetStringAsync("http://localhost/some/endpoint/");

Esto realiza la solicitud al servicio de Windows, pero no pasa las credenciales correctamente (el servicio informa al usuario como IIS APPPOOL\ASP.NET 4.0). Esto no es lo que quiero que pase .

Si cambio el código anterior para usar a WebClienten su lugar, las credenciales del usuario se pasan correctamente:

WebClient c = new WebClient
                   {
                       UseDefaultCredentials = true
                   };
c.DownloadStringAsync(new Uri("http://localhost/some/endpoint/"));

Con el código anterior, el servicio reporta al usuario como el usuario que realizó la solicitud a la aplicación web.

¿Qué estoy haciendo mal con la HttpClientimplementación que hace que no pase las credenciales correctamente (o es un error con HttpClient)?

La razón por la que quiero usar HttpClientes que tiene una API asíncrona que funciona bien con Tasks, mientras que la WebClientAPI asyc de ' debe manejarse con eventos.

adrianbanks avatar Aug 31 '12 16:08 adrianbanks
Aceptado

Puede configurar HttpClientpara pasar automáticamente credenciales como esta:

var myClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
Sean avatar Apr 15 '2013 15:04 Sean

Yo también estaba teniendo este mismo problema. Desarrollé una solución sincrónica gracias a la investigación realizada por @tpeczek en el siguiente artículo SO: No se puede autenticar en el servicio ASP.NET Web Api con HttpClient

Mi solución utiliza un WebClient, que, como señaló correctamente, pasa las credenciales sin problemas. La razón HttpClientpor la que no funciona es porque la seguridad de Windows desactiva la capacidad de crear nuevos subprocesos en una cuenta suplantada (consulte el artículo SO anterior). HttpClientCrea nuevos subprocesos a través de Task Factory, lo que provoca el error. WebClientpor otro lado, se ejecuta sincrónicamente en el mismo hilo, evitando así la regla y reenviando sus credenciales.

Aunque el código funciona, la desventaja es que no funcionará de forma asíncrona.

var wi = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;

var wic = wi.Impersonate();
try
{
    var data = JsonConvert.SerializeObject(new
    {
        Property1 = 1,
        Property2 = "blah"
    });

    using (var client = new WebClient { UseDefaultCredentials = true })
    {
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
        client.UploadData("http://url/api/controller", "POST", Encoding.UTF8.GetBytes(data));
    }
}
catch (Exception exc)
{
    // handle exception
}
finally
{
    wic.Undo();
}

Nota: Requiere el paquete NuGet: Newtonsoft.Json, que es el mismo serializador JSON que utiliza WebAPI.

Joshua avatar Oct 01 '2012 14:10 Joshua

Lo que está intentando hacer es lograr que NTLM reenvíe la identidad al siguiente servidor, lo cual no puede hacer; solo puede realizar una suplantación que solo le brinda acceso a los recursos locales. No te permitirá cruzar el límite de una máquina. La autenticación Kerberos admite la delegación (lo que necesita) mediante el uso de tickets, y el ticket se puede reenviar cuando todos los servidores y aplicaciones de la cadena están configurados correctamente y Kerberos está configurado correctamente en el dominio. En resumen, debe pasar del uso de NTLM a Kerberos.

Para obtener más información sobre las opciones de autenticación de Windows disponibles y cómo funcionan, comience en: http://msdn.microsoft.com/en-us/library/ff647076.aspx

BlackSpy avatar Aug 31 '2012 20:08 BlackSpy