如何设置WCF安全性以要求客户端证书?

问题描述:

我有WCF服务。我要求客户用证书进行认证。 这是服务配置:如何设置WCF安全性以要求客户端证书?

<system.serviceModel> 
     <services> 
      <service name="FilmLibrary.FilmManager" behaviorConfiguration="FilmService.Service1Behavior"> 
       <endpoint address="manager" name="certBinding" binding="basicHttpBinding" contract="FilmContract.IFilmManager" /> 
      </service>    
     </services> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="certBinding"> 
        <security mode="Message"> 
         <message clientCredentialType="Certificate" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="FilmService.Service1Behavior"> 
        <serviceCredentials> 
         <clientCertificate> 
          <authentication trustedStoreLocation="LocalMachine" 
          certificateValidationMode="PeerTrust" /> 
         </clientCertificate>            
        </serviceCredentials>  
      </behavior> 
      </serviceBehaviors> 
     </behaviors> 
    </system.serviceModel> 
</configuration> 

公共密钥安装在LOCALMACHINE,信任的人

客户端的配置如下:

<system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="certBinding" closeTimeout="00:01:00" openTimeout="00:01:00" 
        receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" 
        bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
        useDefaultWebProxy="true"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <security mode="Message"> 
         <message clientCredentialType="Certificate"/> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <behaviors> 
      <endpointBehaviors> 
       <behavior name="certBehaviour"> 
        <clientCredentials> 
         <clientCertificate findValue="SubjectKey" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/> 
        </clientCredentials> 
       </behavior> 
      </endpointBehaviors> 
     </behaviors> 
     <client> 
      <endpoint address="[...]/Service1.svc/manager" 
       binding="basicHttpBinding" bindingConfiguration="certBinding" behaviorConfiguration="certBehaviour" 
       contract="FilmsService.IFilmManager" name="certBinding" /> 
     </client> 
    </system.serviceModel> 

私有密钥安装在个人,当前用户。

没有安全性,服务工作。启用安全性 - 不会。我尝试了几种配置,发现身份验证失败或我必须在clientCredentials元素中设置服务证书等错误。我不明白,因为我根本不想验证服务。

而不是

  <serviceCredentials> 
       <clientCertificate> 
        <authentication trustedStoreLocation="LocalMachine" 
        certificateValidationMode="PeerTrust" /> 
       </clientCertificate>            
      </serviceCredentials> 

我想你应该有

  <serviceCredentials> 
       <serviceCertificate findValue="SubjectKey" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>            
      </serviceCredentials> 

您不受此认证服务,而不是你说的是服务的客户端是如何进行认证。

+3

我想验证客户端,而不是服务。 – jlp 2009-12-06 11:02:31

我能够通过使用customBinding来完成同样的事情,就像这样:

<customBinding> 
    <binding name="bindingName"> 
     <security authenticationMode="UserNameOverTransport" /> 
     <httpsTransport requireClientCertificate="true"/> 
    </binding> 
    </customBinding> 

(我忽略了你的情况不相关的属性)

至于authenticationMode,我想你可以使用它们中的任何一个 - httpsTransportrequireClientCertificate是这里的重要部分。

我发现以下指南非常有帮助和非常详细。 https://notgartner.wordpress.com/2007/09/06/using-certificate-based-authentication-and-protection-with-windows-communication-foundation-wcf/

它涵盖了创建服务,客户端,证书和调整2配置。

服务器:

<bindings> 
    <basicHttpBinding> 
    <binding name="secureHttpBinding"> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="Certificate" /> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

<behaviors> 
    <serviceBehaviors> 
    <behavior> 
     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
     <serviceCredentials> 
     <clientCertificate> 
      <!--only accept certificates in "Trusted People"--> 
      <authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" /> 
     </clientCertificate> 
     </serviceCredentials> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

客户:

<bindings> 
    <basicHttpBinding> 
    <binding name="customBinding1"> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="Certificate" /> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

<behaviors> 
    <endpointBehaviors> 
    <behavior name="customBehavior1"> 
     <clientCredentials> 
     <!--fabrkam--> 
     <clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="d2 31 6a 73 1b 59 68 3e 74 41 09 27 8c 80 e2 61 45 03 b1 7e"/> 
     </clientCredentials> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

我们自动重定向任何HTTP请求到HTTPS,所以我们必须使用TransportWithMessageCredential类型的安全性。对于正常的Http只使用Message作为安全类型也应该起作用。

+0

仅仅为答案添加链接并不是一个好策略。告诉我们为什么链接的内容是有用的,并提供一个可行的例子。 – Athafoud 2015-11-06 13:12:02