【问题标题】:How to set WCF security to require client certificate?如何将 WCF 安全设置为需要客户端证书?
【发布时间】:2010-12-23 14:42:15
【问题描述】:

我有 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 元素中设置服务证书等错误。我不明白,因为我根本不想对服务进行身份验证。

【问题讨论】:

    标签: wcf security certificate


    【解决方案1】:

    我发现以下指南非常有用且非常详细。 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 类型的安全性。对于仅使用 Message 作为安全类型的普通 Http 也应该可以工作。

    【讨论】:

    • 仅仅为答案添加链接不是一个好策略。告诉我们链接的内容为何有用,并在可行的情况下提供示例。
    【解决方案2】:

    我可以通过使用 customBinding 来完成同样的事情,如下所示:

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

    (我省略了与您的案例无关的属性。)

    至于authenticationMode,我认为您可能可以使用它们中的任何一个——httpsTransportrequireClientCertificate 是这里的重要部分。

    【讨论】:

      【解决方案3】:

      代替

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

      我认为你应该有

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

      你不是通过这个来验证服务,而是告诉服务如何验证客户端。

      【讨论】:

      • 我想验证客户端,而不是服务。
      猜你喜欢
      • 2012-02-25
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 2020-08-16
      相关资源
      最近更新 更多