AJAX JSON POSS support for RESTful WCF support using transportCredentialOnly security

I already wrote about this on this topic, but a year later, when I worked with other things, I again managed to get into the brine. I will try to give a brief overview of the scenario and ongoing attempts to get the job done:

  • IIS web server hosting HTML, JS, etc. host: iis.mycompany.com (called foo)
  • WCF RESTful web services hosted through a Windows service on a host: wcf.mycompany.com (called a bar)

Javascript served with foo makes RESTful ajax calls ( GET or POST depending on the action) to the WCF services in the panel, obviously these are cross-calls because they are not on the same host.

Javascript uses the jQuery structure (1.7.2) to control the DOM and make ajax calls for the bar, the expected content type for POSTS is JSON , and it is expected that the response from GETS will be JSON too (application / json).

The bar has WCF services configured using TransportCredentialOnly as the security mode, and the credit type of the transport client is NTLM , so only users with offline access can access the services.

CORS support was added to WCF services in the bar using the extension for WCF:

http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx

We added additional headers and slightly changed that the message was already contained on the basis of numerous Internet articles:

 property.Headers.Add("Access-Control-Allow-Headers", "Accept, Content-Type"); property.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); property.Headers.Add("Access-Control-Max-Age", "172800"); property.Headers.Add("Access-Control-Allow-Origin", "http://iis.mycompany.com"); property.Headers.Add("Access-Control-Allow-Credentials", "true"); property.Headers.Add("Content-type", "application/json"); 

Sites that provide information on enabling CORS suggest that the response header of the Access-Control-Allow-Origin should be set to "*" , but this is not possible in our case, because we make jQuery ajax calls using the following setting:

 $.ajaxSetup({ cache: "false", crossDomain: true, xhrFields: { withCredentials: true } }); 

As it turns out, you cannot use "*" for the accepted beginning when using "withCredentials" in an ajax call:

https://developer.mozilla.org/en/http_access_control

"Important note: when responding to a trusted request, the server must specify a domain and cannot use wild carding."

Currently, this does not matter in our development lab, as we can hard-code requests to the IIS server URL (foo).

Currently, the main problem is trying to execute POST requests ( GET works using the above configuration). When the browser tries to execute the POST process, it first sends the OPTIONS header to the server, asking for the allowed OPTIONS for the subsequent message. Here we would like to see that the headers that we configured in the CORS Support WCF extension are passed back, however we are not getting this far; before the response returns as โ€œ401 Unauthorizedโ€, I believe this is due to the migration security binding configuration requesting NTLM, but I'm not sure.

In addition, I am not very good at it, but I did not see much information about POST using the content type application/json , and not text/plain when making requests to cross domains.

I know that people would probably suggest JSONP as the only true solution, I am not opposed to different approaches, and indeed, I urge someone to suggest best practices, as this would help others who read this question later. However, please try to answer the question before offering alternatives to it.

Many thanks in advance to everyone who contributes.

peteski :)

UPDATE:

It seems that Chrome (20.xx) does not suffer from the problem of not negotiating NTLM in order to get the OPTIONS header response from the server, but Firefox (13.0.1).

We also noticed that someone had already posted an error on the Firefox forum, to which we added information:

http://bugzilla.mozilla.org/show_bug.cgi?id=751552

Please vote for this bug, which will be fixed on the bugzilla website!

Using the following code, we can monitor the network trace to see that Firefox is not working and Chrome is working fine:

 var url = "http://myWebServiceServer/InstantMessagingService/chat/message/send"; var data = '{ "remoteUserUri" : "sip:foo.bar@mydomain.com", "message" : "This is my message" }'; var request = new XMLHttpRequest(); request.open("POST", url, true); request.withCredentials = true; request.setRequestHeader("Content-Type", "application/json"); request.send(data); console.log(request); 

In a separate note, IE8 does not support XMLHttpRequest for cross domain calls, preferring its own magic XDomainRequest object, so we need to do some work to change the client-side code to handle IE8 vs world affairs. (Thanks IE8).

/ me crosses fingers that Mozilla fixes a Firefox bug.

UPDATE 2:

After some digging, it appears that IE8 XDomainRequest cannot be used to create cross-domain queries where NTLM needs to be negotiated, which basically means that the security of our WCF binding cannot be used due to limitations in the web browser.

http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

โ€œNo authentication or cookies will be sent with the requestโ€

So, I think we took it while it goes on. It looks like we will need to create our own token authentication and pass it to the WCF service in a cookie, or in the case of IE8, POST using JSON. Then the WCF service will have to process the decryption of the data and use it instead of ServiceSecurityContext.Current.WindowsIdentity , with which we previously had access using NTLM auth.

+8
javascript authentication rest cross-domain wcf
source share
1 answer

I know that you said that you want to solve the problem more likely, but you can use the "reverse proxy".

I do not know what technologies you use, but we use the Apache web server and have a Java RESTful API running on another server that requires authentication. For a while, we mixed up JSONP and CORS, but were not satisfied.

In the end, we configure Apache Reverse Proxy and work on miracles. The web browser believes that it communicates with its own domain and acts accordingly. The RESTful API does not know that it is used through a proxy. Therefore, everything works. And Apache does all the magic.

We hope that all web servers have a feature like Apache reverse proxy. Here is some documentation on this feature: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

All we had to do was make sure the mod_proxy module was installed, and then add the following lines to our Apache configuration file:

 ProxyPass /restapi http://restfulserver.com/restapi ProxyPassReverse /restapi http://restfulserver.com/restapi 

Then restart the web server and voila!

+1
source share

All Articles