notnot
notnot

Reputation: 4642

jQuery AJAX CORS with ASP.NET WCF service not working despite web.config entries

I'm trying to figure out what it is I'm missing in my approach that's preventing my WCF service from being accessed. If I try to access the service via an AJAX request from the same domain, there's no issue.

I've taken the advice I've seen elsewhere on the site to add to the <httpProtocol> tag in the web.config in order to enable CORS, but it doesn't seem to be working (note the first few elements in customHeaders are there for different security reasons):

<location path="FooBar.svc">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Request-Method" value="POST"/>
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Content-Type, X-Requested-With, X-Custom-Header" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>

Despite this being in place, I still get an error (using IE Developer Tools) when trying to call the service from a separate page: "XMLHttpRequest for ... required Cross Origin Resource Sharing (CORS)"

My jQuery ajax call (Post) has values set for use with CORS, as well:

 crossDomain: true,
 xhrFields: { withCredentials: true },

I've even tried adding a fix for potential IE XDR issues, from https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js, with no effect (I'm using IE11, so I wouldn't expect it)

Anyone have any ideas as to what might be going wrong here?

(EDIT: the service itself is set up with these Attributes, if it makes a difference:

[OperationContract]
[WebInvoke(Method = "POST", 
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json)]

)

(EDIT 2: In case it's meaningful, the service has to be part of an all-HTTPS site which uses Forms Authentication - and the service needs to use the same login credentials as the site. )

Upvotes: 12

Views: 2068

Answers (6)

G Brown
G Brown

Reputation: 754

With WCF, you need to do more than just adding the custom headers in web.config. Just editing web.config is sufficient for an ASP.NET Web API, but if that's not what you're working on, you'll need to add custom code to allow the OPTIONS header, within your web service. Basically, you need to create a message inspector and then some endpoint behavior that uses the message inspector class to add the required headers.

For code and an example service, see the WCF page on enable-cors.org.

Upvotes: 4

AbdulRahman Ansari
AbdulRahman Ansari

Reputation: 3057

Have tried adding Access-Control-Allow-Origin in header in Response as following(only if you want your WCF service be accessible from any domain),

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*");

In one of my Web API method, I used UrlReferrer for this. The code looks like following

Uri referredURL = HttpContext.Current.Request.UrlReferrer;
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://" + referredURL.Host);

But this method is little risky, as it is not guaranteed whether you will get the UrlReferrer or not because it depends on the client(browser).

Upvotes: -1

vijayP
vijayP

Reputation: 11512

If your service is on HTTPS and if you are using self signed SSL Certificate then Cross Domain calls will Fail despite web.config setting done for Access-Control-Allow-Origin header. You should try importing Valid SSL Certificate into your IIS and see what you get.

Upvotes: 5

Akki619
Akki619

Reputation: 2432

Enabling CORS to true in backend server where service is hosted should ideally solve the problem. However there is one more way... You can have a wrapper in between jQuery code and WCF service ( Note: It's one of the approach you have to suggest in the team when you do not have the access to modify for example htaccess file in apache where we set the CORS to have access to other domain accessing our service). So the approach goes like this....

jQuery Code -> Wrapper (Webmethod in .NET) -> WCF service

jQuery code and Wrapper resides in the same domain. jQuery calls webmethod which in turn fire a call to respective WCF service method to get the data. The downfall of this approach is that the request traverse through one more layer, the reason why I have mentioned Note in the beginning.

Upvotes: 7

Roman Pletnev
Roman Pletnev

Reputation: 6138

Your <customHeaders> web.config section is set up for CORS requests without credentials. You need a different configuration to allow CORS requests with credentials:

  1. Set an additional Access-Control-Allow-Credentials header to true.

  2. Access-Control-Allow-Origin header cannot be set to *. You have to return a case-sensitive match for the CORS request origin/host.

Source: 7.2 Resource Sharing Check (W3C Recommendation for Cross-Origin Resource Sharing)

Upvotes: 6

Andi AR
Andi AR

Reputation: 2918

Have you tried with $.support.cors = true in jquery.

Upvotes: 4

Related Questions