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

如何强制WCF客户端发送客户端证书?

  •  13
  • Mark  · 技术社区  · 15 年前

    我正在尝试通过https访问一个公共托管SOAP web服务(而不是WCF),我得到了一个以前从未见过的错误。首先,以下是事实:

    • 我知道URL是可用的,因为我可以在Internet Explorer中点击它。IE会弹出“选择证书”窗口,如果我选中它(并忽略服务器主机名与证书不匹配的错误),它会继续并给出一个HTTP 500错误。
    • 如果我在Chrome中打开站点,在选择证书并忽略错误之后,我会得到一条关于WSA Action=null的正常错误消息。
    • 如果我在FireFox中打开站点,忽略错误后,我会得到一个关于服务器无法验证我的证书的页面。它从来没有让我选一个,所以这很有道理。

    现在,例外:

    Error occurred while executing test 12302: System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'ihexds.nist.gov:9085'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
       at System.Net.HttpWebRequest.GetResponse()
       at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
    

    我已经追踪到了与WireShark的交互,但是因为我不是TLS协议的专家,所以我可能会错过关于发生了什么的线索。然而,我看到的是:

      • 包含随机数、日期/时间、支持的cypher套件等
    1. S->C服务器你好,证书,证书请求,服务器你好完成
      • 包含服务器的证书和对客户端证书的请求
      • 这是有趣的部分。 --此数据包的第一部分是证书握手,我假设客户端证书是,但不存在证书(证书长度:0)。
    2. S->C警报(级别:致命,说明:证书错误)

    我的装订设置如下:

    <binding name="https_binding">
        <textMessageEncoding />
        <httpsTransport useDefaultWebProxy="false" />
    </binding>
    

    我的行为如下:

    <behavior name="clientcred">
        <clientCredentials>
            <clientCertificate findValue="69b6fbbc615a20dc272a79caa201fe3f505664c3" storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" />
            <serviceCertificate>
                <authentication certificateValidationMode="None" revocationMode="NoCheck" />
            </serviceCertificate>
        </clientCredentials>
        <messageInspector />
    </behavior>
    

    我的端点设置为同时使用绑定和行为。为什么WCF在创建https连接时拒绝发送证书?

    3 回复  |  直到 15 年前
        1
  •  9
  •   Mark    15 年前

    我解决了这个问题,但我不明白为什么这个配置改变了它。我改了这句话:

    <httpsTransport useDefaultWebProxy="false" />
    

    对此:

    <httpsTransport useDefaultWebProxy="false" requireClientCertificate="true" />
    

    requireClientCertificate “旋钮”是服务器端的,所以我在争吵时没有试过。显然我错了。

        2
  •  2
  •   user207421    15 年前

        3
  •  0
  •   magnus    15 年前

    协商使用哪种安全协议可能是个问题。特别是我认为服务器可能不喜欢WCF尝试使用TLS 1.0。

    若要查看是否是这种情况,请在调用服务之前尝试添加以下内容

    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3
    

    可以将其添加到客户端代码中,也可以将其放置在IEndpointBehavior中