什么会导致Internet Explorer替换HTTP标头
Authorization : Bearer <server-provided-token>
与
Authorization : Negotiate <some token>
发出AJAX请求时?
详情
在Internet Explorer中,一些配置为包含标题Authorization: Bearer ...
的AJAX请求由Internet Explorer发送,而标题为Authorization: Negotiate ...
。
例如,Fiddler显示三个请求中的前两个包含Authorization : Bearer...
标头,而第三个请求突然包含Authorization : Negotiate...
标头。前两个请求成功,第三个请求失败,因为请求无法正确验证。
所有请求都是使用相同的客户端代码构建的,并且是一个接一个地发出的(在一秒钟内)。我已经验证Authorization
标头在所有三种情况下都正确包含Bearer
令牌,直到请求提供给浏览器为止。
另外,我在Chrome中看不到相同的行为;它只发生在IE中。
请求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
请求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>
请求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
请求是通过AngularJS $http
服务进行的,后端是IIS中托管的ASP.NET Web API。
答案 0 :(得分:16)
我们遇到了Internet Explorer缓存凭据的问题。我们可以使用以下脚本解决问题:
document.execCommand('ClearAuthenticationCache', 'false');
请参阅:Wikipedia
答案 1 :(得分:6)
我也遇到过这个问题。
奇怪的是它在我的开发机器上运行良好,当我部署它时问题就出现了。 它再次在Chrome,Firefox等中运行良好。
事实证明,问题是IE检测到该网站位于localintranet区域,因此尝试自动尝试登录(它是由组策略设置的 - 这是一个内部应用程序)。
我的解决方法是(幸运的是)它只是在使用不是FQDN的服务器名称(例如myserver)时自动检测本地Intranet区域 - 而是使用完整的A
答案 2 :(得分:5)
我在knockoutjs应用程序中遇到了同样的问题,它在Chrome和Firefox中运行良好但在IE中却没有。
我还使用了Fiddler并注意到第一个ajax调用使用了Bearer,并成功返回。但随后IE开始循环并反复使用协商授权发送随后的ajax调用!
在我的情况下,这是IE中的某种计时问题,我通过在渲染同步期间进行加载数据的ajax调用来解决它。
me.loadLimits = function () {
$.ajax({
type: 'GET',
dataType: 'json',
contentType: 'application/json',
url: '/api/workrate/limits',
headers: me.headers,
async: false,
success: function (result) {
...
答案 3 :(得分:4)
当我在我的角度应用程序中启动多个数据加载时,我也遇到了这个问题。
我通过检测浏览器解决了这个问题,如果IE,根据呼叫索引将每个请求延迟50毫秒:
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);
});
有趣的是,当我使用$timeout
时,我不得不将延迟时间增加到100毫秒。
答案 4 :(得分:3)
我们遇到了类似角度和网络api的问题。当系统尝试访问启用了Windows身份验证的根级别的某些资源时,会出现问题。在我们的例子中,应用程序试图从IIS根目录获取favicon。一旦此请求未经授权,IE将尝试使用协商头获取资源;虽然它又失败了。但是从这一点开始,IE继续发送协商头而不是我们的承载令牌。这是由于IE中的设置,我认为是在Internet选项中 - &gt;高级标签 - &gt;在安全部分启用集成Windows身份验证(不确定,我忘记了确切的内容)。
修复是对根级别或应用程序尝试访问的资源位置(错误选项)进行匿名访问,还是具有document.execCommand('ClearAuthenticationCache',false);在app.js文件中。
答案 5 :(得分:0)
在我的情况下,IE在发送错误请求之间交替,然后在第二次尝试时发出良好请求,然后再次发出错误请求,依此类推。
在尝试了几种使IE重试的方法之后 - 看起来在Location头中返回具有相同请求url的307(临时重定向)解决了这个问题。
e.g。请求“http://myUrl/api/service/”
HTTP 307 Temporary Redirect
Location: http://myUrl/api/service/
IE使用正确的数据重试该呼叫。
编辑:此方法可能很危险,因为它可能会创建无限循环。解决它的一个可能的解决方案是返回一些计数器作为Location头中url的一部分,并在再次接收调用时对其进行分析。