使用客户端证书的WCF服务需要IIS中的匿名访问,因此实际上不起作用?

时间:2012-02-22 02:53:58

标签: wcf iis-7.5 wcf-security wcf-client

我有一个托管在IIS中的WCF服务(.NET 4)(Windows Server 2008 R2上的7.5)。我们的客户(我们正在为其构建服务)要求使用Verisign的证书对服务的所有客户端进行身份验证。也就是说,客户从Verisign购买证书并向我们提供公钥。该服务应该只接受可以使用我们从客户端收到的公钥之一进行验证的请求。

我遇到的问题是IIS似乎要求启用匿名身份验证。如果不是,则“此服务的安全设置需要'匿名'身份验证,但不会为承载此服务的IIS应用程序启用它。”提出错误。但是,如果启用匿名身份验证,则允许对提供任何证书的服务进行任何调用。我们需要将其限制为仅允许提供特定证书的呼叫(即我们为其提供公钥的证书)。

在IIS中,我们需要SSL和客户端证书(在SSL设置下),并且(在身份验证下)禁用所有身份验证(匿名除外)。

web.config是:

  <system.web>
    <compilation debug="false" targetFramework="4.0" />
    <authentication mode="Windows" />
    <authorization>
      <deny users="?" />
      <allow users="*" />
    </authorization>
    <customErrors mode="Off" />
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
    <identity impersonate="false" />
  </system.web>

  <system.serviceModel>
    <services>
      <service behaviorConfiguration="XXXServiceBehavior" name="XXXService.NewService">
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="XXXServiceBinding"
                  contract="XXXService.INewService"
                  bindingNamespace="http://XXXX.com.au/XXXService/NewService">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="XXXXServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust" mapClientCertificateToWindowsAccount="true" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="XXXServiceBinding" maxReceivedMessageSize="1000000" maxBufferPoolSize="1000000">
          <readerQuotas maxStringContentLength="1000000" />
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

如果有人能够使这种情况有效,请告诉我您在IIS和配置中使用的设置?

1 个答案:

答案 0 :(得分:1)

事实证明,我需要的是使用TransportWithMessageCredential的绑定安全模式以及message的{​​{1}} clientCredentialType(请参阅下面的完整配置列表) 。

使用此绑定配置,我不需要请求主体权限或证书到Windows帐户的任何映射,因为如果调用者未提供已识别的证书(即其公钥的证书),则不会执行该服务已被导入到服务器上的“受信任人”存储中,在机器级别。)

唯一的其他设置更改是在IIS和SSL设置中。我必须将“客户端证书”设置从“要求”更改为“接受”。 (将其保留为“需要”会导致“客户端身份验证方案'匿名'禁止HTTP请求”。客户端收到错误。)我不确定为什么会这样,但我不认为这是一个问题,因为WCF将需要证书。

所以这是相关的配置。这是服务器配置:

Certificate

这是客户端配置(主要由Visual Studio生成):

<system.web>
  <compilation debug="false" targetFramework="4.0" />
  <authentication mode="Windows" />
  <authorization>
    <deny users="?" />
    <allow users="*" />
  </authorization>
  <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
  <identity impersonate="false" />
</system.web>

<system.serviceModel>
  <services>
    <service behaviorConfiguration="XXXWebServiceBehavior" name="XXXWebService.NewService">
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="XXXWebServiceBinding" contract="XXXWebService.INewService" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="XXXWebServiceBehavior">
        <serviceDebug includeExceptionDetailInFaults="false" />
        <serviceCredentials>
          <clientCertificate>
            <authentication certificateValidationMode="PeerTrust" />
          </clientCertificate>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="XXXWebServiceBinding" maxReceivedMessageSize="1000000" maxBufferPoolSize="1000000">
        <readerQuotas maxStringContentLength="1000000" />
        <security mode="TransportWithMessageCredential">
          <message clientCredentialType="Certificate" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
</system.serviceModel>