问题描述
我正在托管输出jsonp的wcf服务。 IIS的响应(启用了Windows身份验证)是
I am hosting a wcf service which outputs jsonp. The response from IIS (with windows authentication turned on) is
经过身份验证的服务不支持跨域javascript回调。
Cross domain javascript callback is not supported in authenticated services.
有办法解决这个问题吗?我必须打开Windows身份验证,但是也想使用wcf来服务我的jsonp
Is there a way to work around this? I must have windows authentication turned on but would like to use wcf as well to server my jsonp
我的网络配置如下
<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>
推荐答案
有点晚了,我知道,但是因为有没有发布答案,我遇到了类似的问题:
A bit late, I see, but since there are no answers posted and I encountered a similar problem:
我能够使用从Windows访问的经过Windows身份验证的WCF服务(在IIs 7.5中托管)的唯一方法跨域客户端是让客户端通过代理进行调用。有一个额外的跳回代理,但现在我不再依赖JSONP。该服务设置了两个端点,soap和json - 我将整个serviceModel卡在底部以供参考。
The only way I was able to use a windows-authenticated WCF service (hosted in IIs 7.5) that was accessed from a cross-domain client was to have the clients call through a proxy. There’s an extra hop back to the proxy, but now I no longer rely on JSONP. The service is setup with two endpoints, soap and json – I stuck the entire serviceModel at the bottom for reference.
所以客户端应用程序(都是.NET网络应用程序) )或者:
So the client apps (which are all .NET web apps) either:
A)对页面方法(或[HttpPost] MVC控制器方法)进行$ .ajax POST,该方法将WCF称为soap Web引用:
A) Make an $.ajax POST to a page method (or [HttpPost] MVC controller method) which calls the WCF as a soap web reference:
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)为HttpHandler创建$ .getJSON,如Dave Wards中所述
B) Make a $.getJSON to an HttpHandler, as described in Dave Wards http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/
在上面的示例中,处理程序的ProcessRequest方法中的WebClient.DownoadString()将采用以下url字符串:
In the example above the WebClient.DownoadString() in the handler’s ProcessRequest method would take the following url string:
这两种方法都允许我的服务保持在Windows身份验证下,并且客户端有一些访问服务的方法。额外的跳是令人生气的,但我尽量不考虑它。
Both approaches allow my service to remain under windows auth and the clients have a couple means of accessing the service. The extra hop is irritating, but I try not to think about it.
这里是整个WCF serviceModel供参考:
And here’s the entire WCF serviceModel 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"/>
一个补充 - 上述示例方法的OperationContract在ServiceContract中设置如下:
One addition - the OperationContract for the above sample method is setup as follows in the ServiceContract:
[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "EmployeeSearch/{name}")]
List<Employee> EmployeeSearch(string name);
这篇关于使用Windows身份验证的WCF jsonP - 可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!