【问题标题】:Failed to Execute URL when calling a WCF service with Windows authentication使用 Windows 身份验证调用 WCF 服务时执行 URL 失败
【发布时间】:2012-03-30 19:51:26
【问题描述】:

我在部署 WCF 服务的其中一台服务器(它是 Windows Server 2008 R2 机器)上使用 Windows 身份验证时遇到问题,而它在我有权访问的所有其他机器(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 的细节。在有问题的服务器 (~/Service1.svc/problem) 和工作服务器 (~/Service1.svc) 之间,具有相对地址的端点的 HttpRequest.CurrentExecutionFilePath 属性值不同。虽然我对 IIS 不太熟悉,但我怀疑这可能暗示了问题的原因——也许与请求的路由有关?

我的想法已经用完了,因此我在此处发布此内容,希望有人能认识到问题所在。欢迎提出任何建议。

【问题讨论】:

  • 您是否打开了 IIS 上的 URL 重写?这闻起来像是某种许可问题。 What is the difference between Classic and Integrated pipeline mode in IIS7? 可能会有所帮助。
  • @PetarVucetin 我检查了服务器上没有启用 URL 重写。虽然您的评论并没有完全回答我的问题,但您提供的链接给了我一些想法——我设法重新配置我的应用程序,使其在问题不会出现的集成管道模式下工作。我仍然想知道如何使其在经典管道模式下工作,但如果我没有得到更好的答案来澄清这一点,那么您的评论是赏金的最佳人选。毕竟,它确实让我解决了眼前的问题。
  • 谢谢达米尔。当我有时间时,我可以尝试重现这个问题。它只是让我的调试骨头发痒......
  • @PetarVucetin 赏金即将到期。您仍然是我的最佳候选人,但您需要添加答案,因为我无法将其授予评论。

标签: wcf iis iis-7.5 windows-authentication


【解决方案1】:

您是否打开了 IIS 上的 URL 重写?这闻起来像是某种许可问题。 What is the difference between Classic and Integrated pipeline mode in IIS7? 可能会有所帮助。

【讨论】:

  • 感谢您的链接。它让我了解了这些差异,最后我设法让我的应用程序在集成管道模式下工作。不过,我仍然很好奇为什么它不能在该服务器上的经典管道模式下工作。
【解决方案2】:

问题可能是地址“~/Service1.svc/problem”

当地址为“~/Service1.svc”时,调用会命中 svc 文件,并使用文件中的信息来查找接口,然后为该接口进行配置。

当你使用没有 svc 文件的相对地址时,它会查看配置文件中的地址。

您在其中一台服务器上是否有目录“Service1.svc”,或者它所在的服务器上是否有没有“.svc”的地址?

【讨论】:

  • 两者都不是。在为测试目的进行故障排除期间,我仅使用上述测试项目中的文件在所有服务器上创建了一个新应用程序:Service1.svcWeb.configbin\TestService.dll
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
相关资源
最近更新 更多