WCF分布式开发常见错误(26):Authentication failed

     这个也是WCF分布式安全开发实践过程里常见的错误。  验证失败,因为远端已经关闭传输流。
    WCF 传输安全模式下,客户端和服务器端使用证书进行验证。WSHttpBinding.启动服务宿主程序。
    在进行客户端添加服务引用的时候遇到的错误。导致客户端无法添加服务元数据引用。这个问题我查找完毕后解决了。现在整理一下好给大家参考。
【1】错误信息:
    There was an error downloading 'https://frank-xu2009:8001/mex'.
The underlying connection was closed: An unexpected error occurred on a send.
Authentication failed because the remote party has closed the transport stream.
Metadata contains a reference that cannot be resolved: 'https://frank-xu2009:8001/mex'.
An error occurred while making the HTTP request to https://frank-xu2009:8001/mex.
    This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.The underlying connection was closed: An unexpected error occurred on a send.
Authentication failed because the remote party has closed the transport stream.
If the service is defined in the current solution, try building the solution and adding the service reference again.
【2】中文翻译:
    从'https://frank-xu2009:8001/mex'下载时出现错误。
  基础连接关闭:一个意外错误发生在发送时。
  验证失败因为远端关闭了传输流。
  元数据包含的引用不能解析'https://frank-xu2009:8001/mex',
  当向 https://frank-xu2009:8001/mex发送HTTP请求的时候出现错误。
  这个可能是由于服务器证书没有与HTTP.SYS正确配置。
  这个可能是由于客户端和服务端之间的绑定不匹配所致,基础连接关闭:一个意外错误发生在发送时。
  验证失败因为远端关闭了传输流。  如果服务业在此解决方案里定义,请编译此解决方案然后重新添加服务引用。
【3】问题分析:
     和这个问题的解决方式一样: http://social.microsoft.com/Forums/zh-CN/wcfzhchs/thread/54450aa5-27c8-480b-bcfb-e51f7a1e9e35。
    主要还是证书的设置不对。客户端提供的证书出错。制作的客户端证书要安装到服务器证书信任的存储区。
【4】解决步骤:
    修改sky选项为exchange,可以交换密钥。因为要导出带密钥的证书,要安装到信任的证书机构和信任的人。
1.制作一个证书。制作证书: makecert -sr localmachine -ss My -n CN=MyClientCer -sky exchange -pe -r。 http://msdn.microsoft.com/zh-cn/library/aa702761.aspx
2.导出证书文件,带密钥的pfx文件。使用mmc
3.导入证书到信任的人。
4.导入证书到信任的机构,这个证书就被信任了。
【4.1】制作和设置信任证书:
(1)使用makecert 工具:Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示行。
输入: makecert -sr localmachine -ss My -n CN=WCFServerPK -sky exchange -pe -r
输入:makecert -sr localmachine -ss My -n CN=WCFClientPK -sky exchange -pe -r。
-这里制作了连个证书,主要只使用一个WCFServerPK,可以到出密钥文件pfx,后续我们要导入到其他存储区,设置为信任的证书。WCFClientPK -是为以后文章准备的,也是可以设置为信任的证书。

 (2) 打开浏览器---->Internet 选项----->内容----->证书----->个人,默认是保存到当前用户CurrentUser,你会看到刚才制作的证书。这个可以查看部分证书,但是功能有限。我们还是使用控制台证书管理工具。
 (3)使用MMC建立证书控制单元查看证书的信息:
  开始--运行--MMC--控制台--添加删除单元--证书--当前用户和计算机各添加一个。能查看和管理CurrentUser和LocalMachine的证书。如图:
(4)导入证书到信任的人和信任的CA机构里。步骤如下:
    1.导出证书文件,带密钥的pfx文件。使用mmc,保存到桌面位置(方便查找)。这里记住你制作证书的密码。要使用。
    2.导入证书到信任的人。使用任务-导入向导--选择证书文件,导入即可。
    3.导入证书到信任的机构,使用任务-导入向导--选择证书文件,导入即可。这个证书就被信任了。
【4.2】查询SSL证书设置:
     需要为使用的端口SSL注册证书。Windows Server 2003 或 Windows XP,则使用 HttpCfg.exe 工具。Windows Server 2003 中已安装该工具。下载该工具 /Files/frank_xl/HttpcfgFrankXuLei.rar。如果运行的是 Windows Vista,则使用已安装的 Netsh.exe 工具。在Windows\System32目录下。运行此工具需要命令窗口切换到相应工具解压缩目录下,我直接放置到D盘根目录。方便查找。
     (1)在 Windows Server 2003 或 Windows XP 中,通过 queryssl 开关使用 HttpCfg.exe 工具查看当前端口配置,在命令窗口切换到HttpCfg在文件目录,你如下 面代码:
        httpcfg query ssl
  
  (2) Vista:
       netsh http show ss lcert
【4.3】设置SSL证书:

    (1)在 Windows Server 2003 或 Windows XP:
       httpcfg set ssl -i 0.0.0.0:9001-h 9174185b2860b6d5ec3de133d5fcc4e1419b09e5
    (2)Vista:
       netsh http add sslcert ipport=0.0.0.0:9001 certhash=9174185b2860b6d5ec3de133d5fcc4e1419b09e5
  appid={11111111-2222-3333-4444-qqqqqqqqqqqqq} 。最后一个GUID.你可以随便编写一个。使用工具也可以。certhash 参数指定证书的指纹。ipport 参数指定 IP 地址和端口,功能类似于前述 Httpcfg.exe 工具的 -i 开关。appid 参数为可用于标识所属应用程序的 GUID。
 【4.4】删除SSL证书:
    (1)Windows Server 2003 和 Windows XP 中:
    httpcfg delete ssl -i 0.0.0.0:9001-h 9174185b2860b6d5ec3de133d5fcc4e1419b09e5
    (2)Vista:
    Netsh http delete sslcert ipport=0.0.0.0:9001。
【4.5】服务器端证书设置:
system.serviceModel >
    
< services >
      
< service behaviorConfiguration = " WCFService.WCFServiceBehavior "  name = " WCFService.WCFService "   >
        
< endpoint 
          address
= " WCFService "  
          binding
= " wsHttpBinding "  
          bindingConfiguration
= " BindingConfiguration "
          contract
= " WCFService.IWCFService " >
        
</ endpoint >
        
< endpoint address = " mex "  binding = " mexHttpsBinding "  contract = " IMetadataExchange "   />
        
< host >
          
< baseAddresses >
            
< add baseAddress = " https://computer:9001/ " />
          
</ baseAddresses >
        
</ host >
      
</ service >
    
</ services >
    
< behaviors >
      
< serviceBehaviors >
        
< behavior name = " WCFService.WCFServiceBehavior " >
          
< serviceMetadata httpsGetEnabled = " true "   />
          
< serviceDebug includeExceptionDetailInFaults = " false "   />
          
< serviceCredentials >
              
< serviceCertificate  storeName = " My "   x509FindType = " FindBySubjectName "  findValue = " WCFServerPK "  storeLocation = " LocalMachine " />
          
</ serviceCredentials >
        
</ behavior >
      
</ serviceBehaviors >
    
</ behaviors >
    
< bindings >
    
< wsHttpBinding >
      
< binding name = " BindingConfiguration " >
        
< security mode = " Transport " >
          
< transport clientCredentialType = " Certificate " />
        
</ security >
      
</ binding >
    
</ wsHttpBinding >
    
</ bindings >

  
</ system.serviceModel >
   
   这里服务器需要导入客户的证书。 过程一样。  由于我们开发制作的都是临时证书,所以犹豫证书设置或者信任问题导致的安全错误最多。有问题可以参考 WCF分布式安全开发实践(5):传输安全模式之Certificate身份验证:Transport_Certificate_WSHttpBinding 的具体步骤。
  
参考资料:
1. http://social.microsoft.com/Forums/zh-CN/wcfzhchs/thread/ce445c55-f549-4207-956e-c75c1805e15b

你可能感兴趣的:(开发,分布式,failed,WCF,休闲)