代码之家  ›  专栏  ›  技术社区  ›  jlp

如何将WCF安全设置为需要客户端证书?

  •  4
  • jlp  · 技术社区  · 16 年前

    我有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元素中设置服务证书。我不明白,因为我根本不想认证服务。

    3 回复  |  直到 10 年前
        1
  •  2
  •   K2so    16 年前

    而不是

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

    我想你应该有

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

    您不是通过这个对服务进行身份验证,而是告诉服务如何对客户机进行身份验证。

        2
  •  3
  •   Tikall    10 年前

    我发现下面的指南非常有用并且非常详细。 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,只使用消息作为安全类型也应该有效。

        3
  •  2
  •   Lee    15 年前

    我可以通过使用自定义绑定来完成相同的事情,如下所示:

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

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

    直到 authenticationMode 我想你可以用它们中的任何一个 httpsTransport 具有 requireClientCertificate 是这里的重要部分。

    推荐文章