【问题标题】:Error accessing web service through SSL from IIS-hosted application从 IIS 托管的应用程序通过 SSL 访问 Web 服务时出错
【发布时间】:2013-02-05 03:11:29
【问题描述】:

这已经困扰我三天了,经过大量的谷歌搜索后,我决定发布一个问题。我有一个 WCF 服务应用程序(“本地服务”),它安全地连接到“远程 Web 服务”(Java)(2 路证书身份验证)。

我的服务端配置:

<system.serviceModel>
  <bindings>
      <basicHttpBinding>
          <binding name="IhAdapterPortBinding" 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="Transport">
                  <transport clientCredentialType="Certificate" proxyCredentialType="None"
                      realm="" />
                  <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
          </binding>              
      </basicHttpBinding>
  </bindings>
  <client>
      <endpoint address="https://someserver.com:8085/IhAdapter" binding="basicHttpBinding"
          bindingConfiguration="IhAdapterPortBinding" contract="IHAdapter.IhAdapter"
          name="IhAdapterPort" behaviorConfiguration="IHAdapterEndpointBehavior" />       
  </client>
<services>
  <service name="SomeCompany.SomeService">
    <endpoint address="" binding="basicHttpBinding"
      contract="SomeCompany.ISomeService" />
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="IHAdapterEndpointBehavior">
             <clientCredentials>
                  <clientCertificate storeLocation="LocalMachine" storeName="My" findValue="123...abc" x509FindType="FindByThumbprint"/>
                  <serviceCertificate>
                       <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
                  </serviceCertificate>
             </clientCredentials>
        </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

现在解决问题。在 Visual Studio Web 开发服务器中托管服务或从本地测试客户端 (.exe) 调用远程服务时,调用成功。但是当本地服务是 IIS 托管(本地主机或其他服务器 IIS)时,我得到异常:

无法为具有权限“https://someserver.com:8085”的 SSL/TLS 建立安全通道

内部异常:

请求被中止:无法创建 SSL/TLS 安全通道。

到目前为止我尝试或检查的内容:

  • 正确的证书存储位置(本地计算机,而不是用户)
  • 私钥权限(去MMC,找到证书,右键,所有任务,管理私钥,设置为所有人的所有权限)
  • 将 IIS 应用程序用户 (Connect As) 设置为具有管理权限的本地用户

还有一件事:当前的远程服务器证书是为另一个主机名颁发的,所以我必须以编程方式覆盖验证。所以要在本地服务中创建一个远程服务对象,我有这些代码行:

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = ((senderParam, certificate, chain, sslPolicyErrors) => true);

IHAdapter.IhAdapterClient ihAdapter = new IHAdapter.IhAdapterClient();

ihAdapter.SomeMethod(parameters); // the exception gets thrown here

我还能错过什么?有什么想法、指点吗?

【问题讨论】:

  • 服务器是否有自签名证书?验证服务证书的颁发者在您的证书存储中是否可用。如果服务使用的是自签名证书,则需要覆盖 ServiceCertificateValidation 方法,该方法会绕过服务器证书验证
  • 在我看来,我设置了这两个:颁发者证书在服务器信任存储中,ServiceCertificateValidation 以编程方式被覆盖。这看起来像 IIS 问题,webdev 服务器或独立 exe 工作正常。
  • 您的客户端证书是否也是自签名的?如果是,那么您是否将其放置在本地计算机中-> 服务器上的受信任存储区
  • 客户端证书不是自签名的,远程服务器不是“我们的”。我认为远程服务器信任我们服务器的证书,因为我可以从自托管本地服务 (exe) 连接并调用它的方法。仅当本地服务由 IIS 托管时才存在问题...
  • 您能否尝试在您的服务上启用跟踪(msdn.microsoft.com/en-us/library/ms733025.aspx)并查看内部堆栈是否有任何异常。

标签: c# wcf iis certificate


【解决方案1】:

好的,回答我自己的问题。

基于此链接:How to give ASP.NET access to a private key in a certificate in the certificate store? 我解决了我的问题。

我的解决方案的关键是这份清单:

  1. 创建/购买证书。确保它有一个私钥。
  2. 将证书导入“本地计算机”帐户。最好使用证书 MMC。 一定要勾选“允许私钥 出口”
  3. 基于此,IIS 7.5 应用程序池的标识使用以下之一:
    • IIS 7.5 网站在 ApplicationPoolIdentity 下运行。使用证书 MMC,将“IIS AppPool\AppPoolName”添加到“本地计算机\个人”中证书的完全信任中。将“AppPoolName”替换为您的应用程序池的名称。
    • IIS 7.5 网站正在网络服务下运行。使用证书 MMC,将“网络服务”添加到“本地计算机\个人”中证书的完全信任中。
    • IIS 7.5 网站在“MyIISUser”本地计算机用户帐户下运行。使用证书 MMC,将“MyIISUser”(一个新的本地计算机用户帐户)添加到“本地计算机\个人”中证书的完全信任中。

我几乎可以肯定地做了所有这些事情,但显然从来没有同时完成。希望这对其他人有帮助。无论如何感谢所有的帮助。

【讨论】:

  • 谢谢!正是我需要的!
【解决方案2】:

我认为所有这些消息都是由于链中的某些机器(客户端、代理、服务器)由于某种原因不“喜欢”证书。

为了详细说明 twk 所说的,如果您使用的是自签名证书,或者您自己的 CA,您需要至少在服务器上的受信任的权威存储中安装签名证书,并且可能在代理上。

我遇到的常见问题:

  • 服务器上的证书未由 PROXY 或 CLIENT 信任的机构签署
  • CLIENT 上的证书未由 PROXY 或 SERVER 信任的机构签署
  • 糟糕,我在创建要安装在客户端上的证书时忘记导出私钥
  • 我的进程没有读取客户端私钥的权限
  • 客户端证书受密码保护,读取证书时我没有指定凭据。

更多信息请访问Could not create SSL/TLS secure channel - Could the problem be a proxy server?

【讨论】:

  • 无代理,服务器之间直接网络连接。本地服务器信任远程服务器的证书,证书的权限设置为所有人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多