Windows Authenticated WCF jsonP - maybe?

I host a wcf service that outputs jsonp. The response from IIS (with Windows authentication enabled) is

Cross-domain JavaScript callbacks are not supported in authenticated services.

Is there any way around this? I have to enable Windows authentication, but would like to use wcf for my jsonp server too

My web configuration is as follows

<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="webHttpBehavior"> <webHttp /> </behavior> </endpointBehaviors> </behaviors> <bindings> <webHttpBinding> <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" > <security mode="TransportCredentialOnly"> <transport clientCredentialType="Ntlm"/> </security> </binding> </webHttpBinding> </bindings> <services> <service name="ServiceSite.CustomersService"> <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="ServiceSite.CustomersService" behaviorConfiguration="webHttpBehavior"/> </service> </services> </system.serviceModel> 
+4
source share
1 answer

A little late, I see, but since there are no answers, and I ran into a similar problem:

The only way I was able to use the WindowsF-authenticated WCF service (hosted in IIS 7.5), accessed from the cross-domain client, was for clients to call through a proxy server. Theres an extra jump back to the proxy, but now I no longer rely on JSONP. The service is configured with two endpoints, soap and json - I bound the entire Model service below for reference.

Thus, client applications (which are also .NET web applications):

A) Make a $ .ajax POST to the page method (or [HttpPost] MVC controller) that calls WCF as a link to the soap network:

 function EmployeeSearch() { var searchname = $("#userSearchText").val(); if (searchname.length > 0) { var d = { name: searchname, pageSize: _pageSize, page: _currentPage }; var jsonData = JSON.stringify(d); if (json.length > 0) { $.ajax({ type: "POST", url: "Home/EmployeeSearch", data: jsonData, contentType: "application/json; charset=utf-8", dataType: "json", success: employeeSearchSuccess, error: onError }); } } } 

And the controller method (or page method):

  [HttpPost] public ActionResult EmployeeSearch(string name, int pageSize, int page) { var client = new EmployeeServiceClient(); var searchResult = client.EmployeeSearch(name); var count = searchResult.Count(); var employees = searchResult.Skip((page - 1) * pageSize).Take(pageSize).ToList(); var viewModel = new EmployeeSearchViewModel { Employees = employees, Size = count }; return Json(viewModel); } 

OR

B) Make $ .getJSON for the HttpHandler as described in the Dave Wards http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/

In the above example, WebClient.DownoadString () in the ProcessRequest method of the handlers will take the following URL string:

http: //server/EmployeeService/EmployeeService.svc/Json/EmployeeSearch/searchstring

Both approaches allow my service to remain under auth windows, and clients have several ways to access the service. The extra jump is annoying, but I try not to think about it.

And here is the whole WCF service for reference:

 <behaviors> <serviceBehaviors> <behavior name="EmployeeServiceBehavior"> <serviceTimeouts transactionTimeout="01:00:00"/> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <dataContractSerializer maxItemsInObjectGraph="2147483647"/> </behavior> </serviceBehaviors> <!-- we'd use this one if we wanted to ignore the 'd' wrapper around the json result ... we don't --> <endpointBehaviors> <!-- plain old XML --> <behavior name="poxBehavior"> <webHttp helpEnabled="true" /> </behavior> <!-- JSON --> <behavior name="jsonBehavior"> <enableWebScript /> </behavior> </endpointBehaviors> </behaviors> <bindings> <basicHttpBinding> <binding name="basicBinding" hostNameComparisonMode="StrongWildcard" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="524288" transferMode="Buffered" messageEncoding="Text" textEncoding="utf-8" bypassProxyOnLocal="false" useDefaultWebProxy="true" > <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/> <!-- use the following for windows authentication --> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" /> </security> </binding> </basicHttpBinding> <webHttpBinding> <binding name="webBinding" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="524288" bypassProxyOnLocal="false" useDefaultWebProxy="true" > <!--crossDomainScriptAccessEnabled="true"--> <!-- use the following for windows authentication --> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" /> </security> </binding> </webHttpBinding> </bindings> <services> <service name="EmployeeService.Wcf.EmployeeService" behaviorConfiguration="EmployeeServiceBehavior"> <endpoint address="Soap" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="EmployeeService.Wcf.IEmployeeService"/> <endpoint address="Json" binding="webHttpBinding" bindingConfiguration="webBinding" behaviorConfiguration="poxBehavior" contract="EmployeeService.Wcf.IEmployeeService" /> </service> </services> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/> 

One addition - OperationContract for the above sample method is set in ServiceContract as follows:

  [OperationContract] [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "EmployeeSearch/{name}")] List<Employee> EmployeeSearch(string name); 
+5
source

All Articles