peticiones length form ejemplo jquery ajax asp.net-mvc iis windows-authentication

jquery - length - Obtener un Desafío NTLM desde un POSTE AJAX en una sola página



load jquery ejemplo (2)

¿Qué está pasando en los métodos de acción que están causando el desafío NTLM? ¿Estás seguro de que estos métodos de acción específicos no están accediendo a otro servidor o a Internet a través de un proxy que requiere autenticación? En su entorno de desarrollo, su usuario o el usuario que ejecuta el grupo de aplicaciones en IIS puede tener los permisos necesarios, pero el usuario en el servidor no puede.

En lugar de arrojar una Excepción clara relacionada con la seguridad, ASP.NET traducirá esto en un desafío NTLM que se devuelve al cliente, y un 401 en caso de credenciales no válidas, en lugar de un 500 que contenga la pila que lo lleve al punto donde el servidor cuenta no tenía suficientes privilegios ...

Todo el misterio aquí. Tengo una aplicación web ASP.NET MVC 4 con Autenticación de Windows que se ha mantenido durante más de 18 meses sin problemas. Recientemente, se implementó en un sitio nuevo y me encontré con el siguiente comportamiento muy extraño.

Estoy utilizando una llamada jQuery 1.8.2 $.ajax para enviar datos POST a los puntos finales del servidor para actualizar los datos. Esto funciona bien, excepto en una página, donde el AJAX POST desencadena una nueva Negociación NTLM. El mismo problema se muestra en Chrome, IE y Firefox. Si bien el problema es el mismo en todos los navegadores, se manifiesta de maneras ligeramente diferentes:

  • Firefox: Recibió una respuesta de Desafío 401 del servidor y muestra un diálogo de nombre de usuario / contraseña que solicita una credencial en un ciclo infinito. La cancelación de las comprobaciones de credenciales hace que la solicitud falle con una respuesta no autorizada.
  • IE: no hay respuesta del servidor y el estado de la solicitud se muestra como "(Abortado)" en el monitor de red
  • Chrome: no hay respuesta del servidor y el estado de la solicitud muestra un "(error)" en el monitor de red.

El problema central parece ser que el encabezado Connection: keep-alive no se envía con la problemática solicitud AJAX, pero sí en los demás casos. Sin embargo, el código JavaScript subyacente es casi idéntico, y las llamadas AJAX funcionan correctamente en un entorno de desarrollo que también está configurado para usar la autenticación de Windows.

Además, intentar establecer el encabezado de solicitud de Connection en la beforeSend llamada beforeSend no tiene ningún efecto.

Cualquier idea sobre la raíz del problema, o formas de aislar cualquier diferencia existente entre los dos POST de AJAX son muy apreciadas.

Código de trabajo y encabezados de solicitud

$.ajax({ url: url, type: "POST", data: $("#myForm").serialize(), cache: false, success: function (response) { } }); Accept:*/* Accept-Encoding:gzip, deflate Accept-Language:en-US,en;q=0.8 Connection:keep-alive Content-Length:621 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Host:www.xxx.yyy.zzz Origin:http://www.xxx.yyy.zzz Referer:http://www.xxx.yyy.zzz/app/resource/path User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 X-Requested-With:XMLHttpRequest

Código fallido y encabezados de solicitud

$.ajax({ url: url, type: "POST", data: data, cache: false, success: function (data, status, xhr) { } }); WARN: Provisional headers are shown Accept:*/* Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Origin:http://www.xxx.yyy.zzz Referer:http://www.xxx.yyy.zzz/app/resource/item/1 User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 X-Requested-With:XMLHttpRequest

También miré el proceso de red en Chrome chrome://net-internals/#events viewer. Aquí está el registro de eventos de la solicitud fallida en el punto en que se desvía de la exitosa. Cuando la solicitud fallida obtiene un "HTTP / 1.1 401 no autorizado", la solicitud correcta obtiene una respuesta "HTTP / 1.1 200 OK", presumiblemente debido a la presencia del encabezado Connection: keep-alive .

2303: URL_REQUEST Start Time: 2015-04-28 13:53:41.788 t=14736 [st= 0] +REQUEST_ALIVE [dt=71] t=14736 [st= 0] URL_REQUEST_DELEGATE [dt=0] t=14736 [st= 0] +URL_REQUEST_START_JOB [dt=70] --> load_flags = 2688000 (BYPASS_DATA_REDUCTION_PROXY | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT) --> method = "POST" --> priority = "LOW" --> upload_id = "0" --> url = "http://..." t=14736 [st= 0] URL_REQUEST_DELEGATE [dt=0] t=14736 [st= 0] HTTP_CACHE_GET_BACKEND [dt=0] t=14736 [st= 0] URL_REQUEST_DELEGATE [dt=0] t=14736 [st= 0] +HTTP_STREAM_REQUEST [dt=0] t=14736 [st= 0] HTTP_STREAM_REQUEST_BOUND_TO_JOB --> source_dependency = 2305 (HTTP_STREAM_JOB) t=14736 [st= 0] -HTTP_STREAM_REQUEST t=14736 [st= 0] +HTTP_TRANSACTION_SEND_REQUEST [dt=0] t=14736 [st= 0] HTTP_TRANSACTION_SEND_REQUEST_HEADERS --> POST ... HTTP/1.1 Host: www.xxx.yyy.zzz Connection: keep-alive Content-Length: 105 Accept: */* Origin: http://www.xxx.yyy.zzz User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 X-Requested-With: XMLHttpRequest Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: http://www.xxx.yyy.zzz/app/resource/item/1 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8 t=14736 [st= 0] HTTP_TRANSACTION_SEND_REQUEST_BODY --> did_merge = true --> is_chunked = false --> length = 105 t=14736 [st= 0] -HTTP_TRANSACTION_SEND_REQUEST t=14736 [st= 0] +HTTP_TRANSACTION_READ_HEADERS [dt=0] t=14736 [st= 0] HTTP_STREAM_PARSER_READ_HEADERS [dt=0] t=14736 [st= 0] HTTP_TRANSACTION_READ_RESPONSE_HEADERS --> HTTP/1.1 401 Unauthorized Content-Type: text/html Server: Microsoft-IIS/7.5 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET X-UA-Compatible: IE=9 Date: Tue, 28 Apr 2015 18:53:41 GMT Content-Length: 1293

Editar

Jugar con diferentes solicitudes desde la consola da la siguiente tabla de resultados (en Chrome). La URL base actual es http://IPAddress /app/topic/item y todas las pruebas simplemente ejecutan un $.ajax({ url: url, type: ''POST'' })

+--------------------------------------+----------------------------+ | URL | Response | +--------------------------------------+----------------------------+ | http://IP/app/topic/item/1/subitem/1 | net::ERR_INVALID_HANDLE | | //IP/app/topic/item/1/subitem/1 | net::ERR_INVALID_HANDLE | | /app/topic/item/1/subitem/1 | net::ERR_INVALID_HANDLE | | 1/subitem/1 | net::ERR_INVALID_HANDLE | | 1/foo | 404 (Not Found) [expected] | | 1 | 302 (Redirect) [expected] | +--------------------------------------+----------------------------+

Debido a que el error solo afecta un subconjunto de los métodos de acción POST en un controlador, al principio pensé que era un problema del lado del servidor, pero después de descubrir el problema del encabezado de Connection faltante, en realidad parece ser un problema del lado del cliente. Exactamente cómo se desencadena el problema sigue siendo un misterio para mí.

También verifiqué que los encabezados de respuesta para la página de trabajo y la página problemática son los mismos. Lo más relevante es que siempre se devuelve el encabezado Persistent-Auth: true en ambos casos.


Algunas suposiciones salvajes:

  • Esto sucede cuando solicita un Rol que no está en las Reclamaciones del usuario actualmente conectado. Verifique que, si está utilizando [Authorize(Roles = "xyz")] , el usuario actual realmente tiene ese rol.

  • No está claro si su aplicación usa una cookie para la autenticación. Si es así, debería verlo con la solicitud. ¿Estás configurando withCredentials: true para cada solicitud?