我在其部署的服务器之一上使用Windows身份验证的WCF服务出现问题(它是Windows Server 2008 R2计算机),而在我可以访问的所有其他计算机上运行良好(Windows 7) ,Windows Server 2008和Windows Server 2008 R2)。我设法用一个非常简单的示例应用程序重现了这个问题,该应用程序或多或少完全排除了我的代码作为问题的原因。
我可以重现问题的最小应用程序是对WCF服务项目模板的一个小修改:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}\nUsername: {1}",
value,
ServiceSecurityContext.Current == null ?
"<null>" :
ServiceSecurityContext.Current.PrimaryIdentity.Name);
}
}
基本上我启用了ASP.NET兼容性(我需要它,因为实际代码使用HttpHandler进行身份验证)并返回经过身份验证的用户的用户名。
web.config
的内容如下:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="HttpWindowsBinding" maxReceivedMessageSize="2147483647">
<readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647"/>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="TestService.Service1" behaviorConfiguration="ServiceBehavior">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="HttpWindowsBinding"
contract="TestService.IService1" />
<endpoint address="problem"
binding="basicHttpBinding"
bindingConfiguration="HttpWindowsBinding"
contract="TestService.IService1" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
注意两个端点:一个具有默认地址,另一个具有相对地址。即使在有问题的服务器上调用第一个也成功,而对第二个调用的调用失败并出现以下错误:
Exception type: HttpException
Exception message: Failed to Execute URL.
at System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.BeginExecuteUrl(String url, String method, String childHeaders, Boolean sendHeaders, Boolean addUserIndo, IntPtr token, String name, String authType, Byte[] entity, AsyncCallback cb, Object state)
at System.Web.HttpResponse.BeginExecuteUrlForEntireResponse(String pathOverride, NameValueCollection requestHeaders, AsyncCallback cb, Object state)
at System.Web.DefaultHttpHandler.BeginProcessRequest(HttpContext context, AsyncCallback callback, Object state)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
当使用经典管道时,调用才会失败(因为HttpHandler我需要它,但即使没有它也可以重现问题)。使用集成管道,问题就消失了。此外,如果我禁用Windows身份验证,问题也会消失:
<binding name="HttpBinding" maxReceivedMessageSize="2147483647">
<readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647"/>
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
我注意到注册了HttpHandler的另一个细节。具有相对地址的端点的HttpRequest.CurrentExecutionFilePath属性的值在有问题的服务器(~/Service1.svc/problem
)和工作服务器(~/Service1.svc
)之间不同。虽然我对IIS不熟悉,但我怀疑这可能暗示问题的原因 - 可能与请求路由有关?
我的想法已经不多了,所以我在这里发帖,希望有人能够认识到问题所在。欢迎提出任何建议。
答案 0 :(得分:1)
您是否在IIS上启用了URL重写功能?这闻起来像是某种许可问题。 What is the difference between Classic and Integrated pipeline mode in IIS7?可能会有所帮助。
答案 1 :(得分:0)
问题可能是地址“〜/ Service1.svc / problem”
当地址为“〜/ Service1.svc”时,该呼叫将命中svc文件,并使用该文件中的信息查找该接口,然后查找该接口的配置。
当你使用没有svc文件的相对地址时,它会查看配置文件中的地址。
您是否在其中一台服务器上有一个目录“Service1.svc”,或者该服务器上没有“.svc”的地址?