7

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
1

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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'
});

3 Comments

anonymous auth is one of the modes switched off in IIS. Normally sharepoint uses Windows Auth.
@Ray thanks for the clarification :) I don't know if that affects passing the username/password properties to $.ajax().
I updated the question - using either username / password, or withCredentials, doesn't seem to work.
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.