Qu'est-ce qui ferait qu'Internet Explorer remplace l'en-tête HTTP?
Authorization : Bearer <server-provided-token>
avec
Authorization : Negotiate <some token>
lors d'une requête AJAX?
Détails
Dans Internet Explorer, certaines demandes AJAX configurées pour contenir l'en-tête Authorization: Bearer ...
sont envoyées par Internet Explorer avec l'en-tête Authorization: Negotiate ...
à la place.
Par exemple, Fiddler montre que les deux premières demandes sur trois contiennent l'en-tête Authorization : Bearer...
, tandis que la troisième contient soudainement l'en-tête Authorization : Negotiate...
. Les deux premières demandes aboutissent et la troisième échoue car la demande ne peut pas être authentifiée correctement.
Toutes les demandes sont construites en utilisant le même code côté client et sont effectuées les unes après les autres (en l'espace d'une seconde). J'ai vérifié que l'en-tête Authorization
contient correctement le jeton Bearer
dans les trois cas jusqu'au point où la demande est fournie au navigateur.
De plus, je ne vois pas le même comportement dans Chrome; cela ne se produit que dans IE.
Demande 1
. .__ GET http: // localhost/myapp/api/utilisateur HTTP/1.1 .__ Accepter:. Application/JSON, text/plain, */* .__ Autorisation:. 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, dégonfler .__ User-Agent. Mozilla/5.0 ( Windows NT 6.1; WOW64; Trident/7.0; vv: 11.0) semblable à Gecko Host: localhost DNT: 1 Connexion: Keep-Alive
Demande 2
POST http: // localhost/myapp/api/Autorisations HTTP/1.1 Référent: http: //localhost/client/#/Dashboard Content-Type: application/json Autorisation: Bearer oEXS5IBu9huepzW6jfh-POMA18AUA8yWZsPfBPZuFf_JJxq-DKIt0JDyPXSiGpmV_cpT8FlL3D1DN-Tv5ZbT73MTuBOd5y75-bsx9fZvOeJgg04JcO0cUajdCH2h5QlMP8TNwgTpHg-TR9FxyPk3Kw6bQ6tQCOkOwIG_FmEJpP89yrOsoYJoCfrAoZ7M4PVcik9F9qtPgXmWwXB2eHDtkls44wITF_yM_rPm5C47OPCvMVTPz30KwoEPi6fHUcL3qHauP-v9uypv2e48TyPHUwLYmNFxyafMhBx4TkovnRcsdLHZiHmSjMq0V9a2Vw70 .__ Accepter:.. application/JSON, text/plain, */* .__ Accept-Language:. en-US .__ Accept-Encoding: gzip, dégonfler User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; vv: 11.0) comme Gecko Host: localhost Longueur du contenu: 1419 DNT: 1 Connexion : Keep-Alive Pragma: no-cache <Données supprimées>
Demande 3
GET http: // localhost/myapp/api/UserPreferences/Tableau de bord HTTP/1.1 Référent: http: //localhost/client/#/Dashboard Content-Type: application/json Autorisation : + Negotiate YHsGBisGAQUFAqBxMG gMDAuBgorBgEEAYI3AgIKBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHqI7BDlOVExNU1NQAAEAAACXsgjiBgAGADMAAAALAAsAKAAAAAYBsR0AAAAPVk1ERVZFTlYtU1JTQ0VSSVM = .__ Accepter:. application/JSON, text/plain, */* .__ Accept-Language:.. en-US .__ Accept-Encoding:. gzip, dégonfler .__ User-Agent: Mozilla /5.0 (Windows NT 6.1; WOW64; Trident/7.0; règle: 11.0) comme Gecko Connexion: Keep-Alive DNT: 1 Host: localhost
Les demandes sont effectuées via le service AngularJS $http
et le back-end est l’API Web ASP.NET hébergée dans IIS.
Nous avons eu un problème où Internet Explorer mettait en cache les informations d'identification. Nous pourrions résoudre le problème en utilisant le script suivant:
document.execCommand('ClearAuthenticationCache', 'false');
voir: Wikipedia
Je viens de rencontrer ce problème aussi.
Ce qui était étrange, c’est que cela fonctionnait bien sur ma machine de développement, c’est lorsque je l’ai déployé que le problème est survenu… .. Cela a encore fonctionné sous Chrome, Firefox, etc.
Il se trouve que le problème est que IE détectait que le site se trouvait sur la zone intranet local et essayait donc d'essayer de se connecter automatiquement (défini par la stratégie de groupe - il s'agit d'une application interne).
Ma solution de contournement était (heureusement) que la détection automatique de la zone Intranet locale s’applique lorsqu’on utilise un nom de serveur qui n’est pas un nom de domaine complet (par exemple, myserver), mais en utilisant le code A complet.
J'ai eu le même problème dans une application knockoutjs, cela fonctionnait bien dans Chrome et Firefox mais pas dans IE.
J'ai également utilisé Fiddler et remarqué que le premier appel ajax utilisait Bearer comme prévu et revenait avec succès. Mais alors IE a commencé à boucler et à envoyer les appels ajax suivants encore et encore avec l'autorisation de négocier!
Dans mon cas, c’était un problème de synchronisation dans IE, je l’ai résolu en effectuant les appels ajax chargés de données lors du rendu synchrone.
me.loadLimits = function () {
$.ajax({
type: 'GET',
dataType: 'json',
contentType: 'application/json',
url: '/api/workrate/limits',
headers: me.headers,
async: false,
success: function (result) {
...
J'ai également rencontré ce problème lorsque je démarrais plusieurs charges de données dans mon application angulaire.
J'ai résolu ce problème en détectant le navigateur et, si Internet Explorer, en retardant chaque requête de 50 ms en fonction de l'index de l'appel:
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);
});
Fait intéressant, quand j'ai utilisé $timeout
, j'ai dû augmenter le délai à 100 ms.
Nous avions rencontré le même problème avec les API Web et angulaires. Ce problème survient lorsque le système tente d'accéder à une ressource au niveau racine sur laquelle l'authentification Windows est activée. Dans notre cas, l'application essayait d'obtenir le favicon de la racine IIS. Une fois cette demande non autorisée, IE essaiera d’obtenir la ressource avec un en-tête de négociation; bien que cela échoue à nouveau. Mais à partir de ce moment, IE continue d’envoyer l’en-tête de négociation au lieu de notre jeton porteur. Cela est dû aux paramètres d'IE, qui, je pense, se trouvent dans Options Internet -> onglet Avancé -> Activer l'authentification Windows intégrée dans la section Sécurité (pas sûr, j'ai oublié le contenu exact).
Le correctif consistait à donner un accès anonyme au niveau racine ou à l’emplacement de la ressource auquel l’app tente d’accéder (option incorrecte) ou d’avoir document.execCommand ('ClearAuthenticationCache', false); dans le fichier app.js.
Dans mon cas, IE alternait entre l'envoi d'une requête incorrecte, suivi d'une requête correcte lors d'une deuxième tentative, puis d'une requête incorrecte à nouveau, etc.
Après avoir essayé plusieurs approches pour provoquer une nouvelle tentative de IE, il apparaît que le renvoi d'une redirection 307 (redirection temporaire) avec la même URL de requête dans l'en-tête Location résout le problème.
par exemple. pour une demande à " http: // myUrl/api/service/ "
HTTP 307 Temporary Redirect
Location: http://myUrl/api/service/
IE relance l'appel avec les données appropriées.
Edit: Cette méthode peut être dangereuse car elle pourrait créer une boucle infinie. Une solution possible pour contourner le problème consiste à renvoyer un compteur dans l'URL figurant dans l'en-tête Location et à l'analyser lors de la réception de l'appel.