错误请求仅在远程计算机上使用IE 11返回,用于传递凭据的XHR

时间:2017-12-20 01:44:12

标签: c# ajax internet-explorer

我一直想弄清楚在为需要Windows身份验证的MS Web API制作XHR时我缺少的是什么。

此请求适用于Chrome和IE 11本地以及远程控制台(不是服务器)上的Chrome。问题是远程盒子上的IE 11。

根据开发工具,IE发出3个请求。前两个请求通过授权:Negotiate标头并返回401s(CORS的预检?)。但是,第三个返回400.它似乎无法以我不理解的方式进行身份验证,特别是因为其他浏览器和本地测试都有效。

API是一个自托管的OWIN控制台应用程序。这是创业公司:

public void Configuration(IAppBuilder appBuilder)
{
    appBuilder.UseCors(CorsOptions.AllowAll);

    var listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];

    if (listener != null)
    {
        listener.AuthenticationSchemeSelectorDelegate = request =>
        {
            if (string.Compare(request.HttpMethod, "OPTIONS", StringComparison.OrdinalIgnoreCase) == 0)
            {
                return AuthenticationSchemes.Anonymous;
            }
            else
            {
                return AuthenticationSchemes.IntegratedWindowsAuthentication;
            }
        };
    }

    var config = new HttpConfiguration();
    config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
    appBuilder.UseWebApi(config);
}

这是客户端XHR调用:

var request = new XMLHttpRequest();
request.open('GET', 'http://xxxx:9000/api/test/something', true);
request.timeout = 10000;
request.withCredentials = true;
request.onload = function() {
    if (request.status >= 200 && request.status < 400) {
        console.log('done');
    } else {
        console.error('error');
    }
};

request.onerror = function() {
    // There was a connection error of some sort
};

request.send();

API控制器:

[Authorize]
[RoutePrefix("api/test")]
public class TestController : ApiController
{
    [HttpGet]
    [ActionName("something")]
    public IHttpActionResult Something()
    {
        return Ok();
    }
}

2返回401的请求和返回400的请求:

First 401:

   Request URL: http://xxxx:9000/xxxx
   Request Method: GET
   Status Code: 401 / Unauthorized

Request Headers
   Accept: */*
   Accept-Encoding: gzip, deflate
   Accept-Language: en-US
   Authorization: Negotiate [token]
   Connection: Keep-Alive
   Host: xxxx:9000
   Referer: http://xxxx/xxxx.html
   User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3)

Response Headers

   Content-Length: 0
   Date: Fri, 22 Dec 2017 14:03:09 GMT
   Server: Microsoft-HTTPAPI/2.0
   WWW-Authenticate: Negotiate [token]

-------------
Second 401

   Request URL: http://xxxx:9000/xxxx
   Request Method: GET
   Status Code: 401 / Unauthorized

Request Headers

   Accept: */*
   Accept-Encoding: gzip, deflate
   Accept-Language: en-US
   Authorization: Negotiate [token]
   Connection: Keep-Alive
   Host: xxxx:9000
   Referer: http://xxxx/xxxx.html
   User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3)

Response Headers

   Content-Length: 0
   Date: Fri, 22 Dec 2017 14:03:09 GMT
   Server: Microsoft-HTTPAPI/2.0
   WWW-Authenticate: Negotiate [token]

-----------
400

   Request URL: http://xxxx:9000/xxxx
   Request Method: GET
   Status Code: 400 / Bad Request

Request Headers

   Accept: */*
   Accept-Encoding: gzip, deflate
   Accept-Language: en-US
   Authorization: Negotiate [token]
   Connection: Keep-Alive
   Host: xxxx:9000
   Referer: http://xxxx/xxxx.html
   User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3)

Response Headers

   Content-Length: 0
   Date: Fri, 22 Dec 2017 14:03:12 GMT
   Server: Microsoft-HTTPAPI/2.0

2 个答案:

答案 0 :(得分:1)

受信任的网站

我的猜测是远程计算机受域策略限制,并且您的站点不被视为该计算机上的可信站点。

添加(或要求添加,如果政策由IT设置)您的网站适当的安全区域(本地Intranet或受信任的站点),问题应该修复。

文档模式

在你了解它的同时,还要看看他们是否正在推动IE11的任何旧文档模式运行。

为WebAPI启用CORS

我发现您已经在OWIN的UseCors上拨打了IAppBuilder,但您还可以尝试在HttpConfiguration个实例上启用CORS:

config.EnableCors(new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS, PUT, DELETE"));

答案 1 :(得分:1)

我使用XHR传递了一个HttpOnly cookie /令牌:

  1. 在客户端上使用axios或类似的库,并使用包含withCredentials的配置:

        import axios from 'axios';
        const config = {
            method: 'get',
            url: 'http://xxxx:9000/api/test/something',
            timeout: 5000,
            withCredentials: true
        };
        //if (setCookie === true) {
            //config.mode = 'no-cors'; // <= THIS IS IMPORTANT IF SETTING COOKIE!
        //}
        const response = await axios(config);
    
  2. 在服务器上设置cors选项:

    const corsOptions = {
        origin: 'http://xxxx:9000', // Set explicit origin!
        methods: ['GET', 'POST', 'PUT', 'DELETE'], // Allow method(s)!
        credentials: true //enable server to see credentials.
    };
    
  3. 来源:xhr.spec.whatwg.org

    我希望它也适合你,它需要一些时间才能运作。如果失败,那么window.postMessage远射可能会起作用。最后,如果您使用的是Windows,也可能是本地问题:

      

    您的网站所处的安全区域是什么(Internet选项&gt;   安全性)确保您在区域中启用以下设置:   其他&gt;跨域访问数据源。