internet - angularjs build prod
Internet Explorer 11 reemplaza el encabezado de autorizaciĆ³n (6)
Qué provocaría que Internet Explorer reemplazara el encabezado HTTP
Authorization : Bearer <server-provided-token>
con
Authorization : Negotiate <some token>
al hacer una solicitud de AJAX?
Detalles
En Internet Explorer, algunas solicitudes AJAX que están configuradas para contener el encabezado Authorization: Bearer ...
están siendo enviadas por Internet Explorer con el encabezado Authorization: Negotiate ...
lugar.
Por ejemplo, Fiddler muestra que las primeras dos de tres solicitudes contienen el encabezado Authorization : Bearer...
, mientras que el tercero contiene de repente el encabezado Authorization : Negotiate...
Las primeras dos solicitudes son exitosas y la tercera falla porque la solicitud no se puede autenticar correctamente.
Todas las solicitudes se construyen utilizando el mismo código del lado del cliente, y se realizan una tras otra (en el lapso de un segundo). He verificado que el encabezado de Authorization
contiene correctamente el token de Bearer
en los tres casos hasta el momento en que se proporciona la solicitud al navegador.
Además, no veo el mismo comportamiento en Chrome; solo está ocurriendo en IE.
Solicitud 1
GET http://localhost/myapp/api/User HTTP/1.1 Accept: application/json, text/plain, */* Authorization: Bearer oEXS5IBu9huepzW6jfh-POMA18AUA8yWZsPfBPZuFf_JJxq-DKIt0JDyPXSiGpmV_cpT8FlL3D1DN-Tv5ZbT73MTuBOd5y75-bsx9fZvOeJgg04JcO0cUajdCH2h5QlMP8TNwgTpHg-TR9FxyPk3Kw6bQ6tQCOkOwIG_FmEJpP89yrOsoYJoCfrAoZ7M4PVcik9F9qtPgXmWwXB2eHDtkls44wITF_yM_rPm5C47OPCvMVTPz30KwoEPi6fHUcL3qHauP-v9uypv2e48TyPHUwLYmNFxyafMhBx4TkovnRcsdLHZiHmSjMq0V9a2Vw70 Referer: http://localhost/client/login.html Accept-Language: en-US Accept-Encoding: gzip, deflate User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Host: localhost DNT: 1 Connection: Keep-Alive
Solicitud 2
POST http://localhost/myapp/api/Permissions HTTP/1.1 Referer: http://localhost/client/#/Dashboard Content-Type: application/json Authorization: Bearer oEXS5IBu9huepzW6jfh-POMA18AUA8yWZsPfBPZuFf_JJxq-DKIt0JDyPXSiGpmV_cpT8FlL3D1DN-Tv5ZbT73MTuBOd5y75-bsx9fZvOeJgg04JcO0cUajdCH2h5QlMP8TNwgTpHg-TR9FxyPk3Kw6bQ6tQCOkOwIG_FmEJpP89yrOsoYJoCfrAoZ7M4PVcik9F9qtPgXmWwXB2eHDtkls44wITF_yM_rPm5C47OPCvMVTPz30KwoEPi6fHUcL3qHauP-v9uypv2e48TyPHUwLYmNFxyafMhBx4TkovnRcsdLHZiHmSjMq0V9a2Vw70 Accept: application/json, text/plain, */* Accept-Language: en-US Accept-Encoding: gzip, deflate User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Host: localhost Content-Length: 1419 DNT: 1 Connection: Keep-Alive Pragma: no-cache <Post Data Removed>
Solicitud 3
GET http://localhost/myapp/api/UserPreferences/Dashboard HTTP/1.1 Referer: http://localhost/client/#/Dashboard Content-Type: application/json Authorization: Negotiate YHsGBisGAQUFAqBxMG+gMDAuBgorBgEEAYI3AgIKBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHqI7BDlOVExNU1NQAAEAAACXsgjiBgAGADMAAAALAAsAKAAAAAYBsR0AAAAPVk1ERVZFTlYtU1JTQ0VSSVM= Accept: application/json, text/plain, */* Accept-Language: en-US Accept-Encoding: gzip, deflate User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Connection: Keep-Alive DNT: 1 Host: localhost
Las solicitudes se realizan a través del servicio AngularJS $http
y el back-end es ASP.NET Web API hospedado en IIS.
En mi caso, IE alternó entre enviar una solicitud incorrecta, seguida de una buena solicitud en un segundo intento, y luego una mala solicitud, y así sucesivamente.
Después de probar varios enfoques para hacer que IE vuelva a intentarlo, parece que devolver un 307 (redireccionamiento temporal) con la misma url de solicitud en el encabezado de ubicación resuelve el problema.
por ejemplo, para una solicitud a " http: // myUrl / api / service / "
HTTP 307 Temporary Redirect
Location: http://myUrl/api/service/
IE vuelve a intentar la llamada con los datos adecuados.
Editar: este método puede ser peligroso ya que podría crear un bucle infinito. Una posible solución para evitarlo es devolver algún contador como parte de la url en el encabezado de ubicación y analizarlo cuando reciba la llamada nuevamente.
Me acabo de encontrar con este problema también.
Lo que es extraño es que funcionó bien en mi máquina de desarrollo, fue cuando lo implementé surgió el problema. Nuevamente funcionó bien en Chrome, Firefox, etc.
Resulta que el problema es que IE detectaba que el sitio estaba en la zona de la intranet local y, por lo tanto, intentaba iniciar sesión de forma automática (lo estableció la política de grupo; esta es una aplicación interna).
Mi solución fue que (afortunadamente) solo detectaba automáticamente la zona de intranet local cuando usaba un nombre de servidor que no era un FQDN (p. Ej., Miservidor), sino que utilizaba el A completo.
Nos habíamos enfrentado a un problema similar con api angular y web. El problema ocurre cuando el sistema intenta acceder a algún recurso en el nivel raíz que tenía habilitada la Autenticación de Windows. En nuestro caso, la aplicación intentaba obtener el favicon de la raíz de IIS. Una vez que esta solicitud se desautoriza, IE intentará obtener el recurso con encabezado de negociación; aunque falla de nuevo. Pero desde este punto en adelante, IE sigue enviando encabezado de negociación en lugar de nuestro token de portador. Esto se debe a la configuración en IE, que creo que está en Opciones de Internet -> pestaña Avanzado -> Habilitar autenticación de Windows integrada en la sección de Seguridad (no estoy seguro, olvidé las cosas exactas).
La reparación era proporcionar acceso anónimo al nivel de raíz o a la ubicación de recursos a la que intenta acceder (opción incorrecta) o tener document.execCommand (''ClearAuthenticationCache'', false); en el archivo app.js.
También me encontré con este problema cuando estaba lanzando múltiples cargas de datos en mi aplicación angular.
Lo solucioné detectando el navegador y, si IE, retrasé cada solicitud en 50 ms en función del índice de la llamada:
return $q(function(resolve, reject) {
var delay = self.widget.useDelayLoading ? self.widget.index * 50 : 0;
setTimeout(function() {
restService.genericApi(self.widget.url, false).queryPost(json).$promise
.then(
function(r) { resolve(r); },
function(e) { reject(e); }
);
}, delay);
});
Curiosamente, cuando usé $timeout
, tuve que aumentar la demora a 100 ms.
Tuve el mismo problema en una aplicación knockoutjs, funcionó bien en Chrome y Firefox pero no en IE.
También utilicé Fiddler y me di cuenta de que la primera llamada ajax utilizaba el portador como se pretendía y se devolvió con éxito. ¡Pero entonces IE comenzó a repetir y enviar las siguientes llamadas ajax una y otra vez con la autorización Negociar!
En mi caso, fue una especie de problema de tiempo en IE, lo resolví haciendo que las llamadas ajax que cargaban datos durante el procesamiento fueran síncronas.
me.loadLimits = function () {
$.ajax({
type: ''GET'',
dataType: ''json'',
contentType: ''application/json'',
url: ''/api/workrate/limits'',
headers: me.headers,
async: false,
success: function (result) {
...
Tuvimos un problema donde Internet Explorer estaba almacenando credenciales en caché. Podríamos solucionar el problema utilizando la siguiente secuencia de comandos:
document.execCommand(''ClearAuthenticationCache'', ''false'');
ver: Wikipedia