将 HTTPS 绑定添加到 IIS 后,具有 Windows 身份验证的 WCF SOAP Web 服务停止工作

WCF SOAP Web Service with Windows Authentication stops working, after adding an HTTPS binding to IIS

我看到了奇怪的行为。当我将 HTTPS 绑定添加到 IIS 时,我的 Web 服务停止工作。无论我是否使用我的服务,都会通过以“http://”或“https://”开头的 URL 发生这种情况。

来自我的服务的错误消息

The authentication schemes configured on the host ('IntegratedWindowsAuthentication') do not allow those configured on the binding 'BasicHttpsBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.

我在 IIS 中添加的 HTTPS 绑定

在 IIS 中对我的服务进行身份验证

我的服务web.config

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

问题

看起来 IIS 默认采用带有匿名身份验证的 basicHttpsBinding。我通过添加一个带有 Windows 身份验证的 basicHttpsBinding 来解决它(同样是无名的,以便它覆盖默认值),在我已经存在的无名 basicHttpBinding.

下面
<basicHttpsBinding>
  <binding name="">
    <security mode="Transport">
      <transport clientCredentialType="Windows" />
    </security>
  </binding>
</basicHttpsBinding>

为此,我使用了内置于 Visual Studio 中的 WCF 配置编辑器。如果有人想知道所有这些设置的来源:

  • 现在,无论 IIS 中是否存在 HTTPS 绑定,它都可以正常工作
  • 我的服务现在也可以通过以“http://”或“https://”开头的 URL 运行

Microsoft 应该为 web.config 提供与 IIS 相同的结构,其中身份验证独立于绑定。如果他们将配置留给 IIS,这样设置就不会发生冲突,那就更好了。他们真的把球丢在了这一个上。

我的新服务web.config

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpBinding>
      <basicHttpsBinding>
        <binding name="">
          <security mode="Transport">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpsBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>