401 when trying to implement CORS for SharePoint

I would like to access listdata.svc (a sharepoint service) located on domainA.contoso.com from a web application located on domainB.contoso.com - Authentication seems to be an issue.

When attempting to access ListData.svc via a JQuery Ajax call, with CORS enabled, the server returns 401. If I run the same Query from an .htm page which I execute from inside of SharePoint, the call works fine, since the domain is the same.

SharePoint is using NTLM with anonymous authentication turned off - I presume that the 401 is a result of windows credentials not being passed to the SharePoint server - but I am at a loss of how to add these credentials properly to the header. I have set xhrFields: { withCredentials: true }, but this does not seem to correct the authentication issue.

To enabled CORS, I have set the following HTTP Response Headers on SharePoint in IIS:

  • Access-Control-Allow-Credentials: true
  • Access-Control-Allow-Headers:Origin, Content-Type, Accept
  • Access-Control-Allow-Origin: *
  • Access-Control-Request-Methods: POST, GET, HEAD, OPTIONS
  • Windows Authentication is enabled in IIS for my web application, and I did not set the "OPTIONSVerbHandler" HTTP Handler in IIS. Turning it to read doesn't seem to make a difference.

    JQuery Ajax call (from application on subdomainB.contoso.com):

     $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            url: listUrl,
            xhrFields: { withCredentials: true },
            crossDomain:true,  
            processData: false,
            async: true,
            dataType: "json",
            converters: {
                // WCF Data Service .NET 3.5 incorrectly escapes singles quotes, which is clearly
                // not required (and incorrect) in JSON specs.
                // http://bugs.jquery.com/ticket/8320?cversion=0&cnum_hist=1
                "text json": function (textValue) {
                    return jQuery.parseJSON(textValue.replace(/(^|[^])'/g, "$1'"));
                }
            },
            success: function (data, status, xhr) {
                //successFunc(data.d.results);
                alert("working!");
            },
            error: function (xhr, status, error) {
                alert("failure!");
            }
        });
    

    HTTP Header and 401 Response:

    Key Value
    Request OPTIONS /_vti_bin/ListData.svc/Contacts HTTP/1.1
    Accept  */*
    Origin  http://domainB.contoso.com
    Access-Control-Request-Method   GET
    Access-Control-Request-Headers  content-type, accept
    Accept-Encoding gzip, deflate
    User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
    Host    domainA.contoso.com
    Content-Length  0
    DNT 1
    Connection  Keep-Alive
    Cache-Control   no-cache
    
    Key Value
    Response    HTTP/1.1 401 Unauthorized
    Server  Microsoft-IIS/7.5
    SPRequestGuid   1e33061c-f555-451b-9d69-0d83eff5f5ea
    WWW-Authenticate    NTLM
    X-Powered-By    ASP.NET
    MicrosoftSharePointTeamServices 14.0.0.4762
    Access-Control-Allow-Headers    Origin, Content-Type, Accept
    Access-Control-Allow-Origin *
    Access-Control-Request-Methods  POST, GET, HEAD, OPTIONS
    Access-Control-Allow-Credentials    true
    Date    Wed, 15 May 2013 15:04:51 GMT
    Content-Length  0
    

    Late response, but I found another thread here which has an easy solution for IIS and which worked for me.

    Basically the CORS standard specifies that a preflight request should not send any authentication information, thus the 401. In that thread there's an example of restricting anonymous requests to the OPTIONS verb which allows a 200 response to the preflight (OPTIONS) verb) request but still requires the authentication for the others.


    I'm not sure what you mean by "anonymous authentication is disabled", but it sounds like that's exactly the reason you're getting a 401 ( Unauthorized ) response. It's not related to CORS, but the server is telling the client it requires a username and a password before it will allow access.

    Try passing a username and password to $.ajax() ( WARNING : it's just to test if that solves your problem, hardcoding such details in your JS code is a Bad Idea):

    $.ajax({
      crossDomain:true,    
      url: listUrl,
      username: VALID_USERNAME,
      password: VALID_PASSWORD,
      success: function(data){alert("hello json!") },
      error: function() {
        alert("epic fail");
      },
      dataType:'json'
    });
    

    You can't use wildcard (*) for Access-Control-Allow-Origin on the server when client sends "withCredentials: true".
    You must set the domain explicitely.
    CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true

    链接地址: http://www.djcxy.com/p/13546.html

    上一篇: 在小部件顶部显示小部件

    下一篇: 401试图实施SharePoint的CORS