最近有个项目要调用客户用java写的带https的webservice,对方提供了证书文件 test.pfx,我这里调用方式如下:

//webservice代理类
SvcService svc = new SvcService();
//证书文件路径
string filePath = ConfigurationManager.AppSettings["pfxUrl"];
X509Certificate cert = new System.Security.Cryptography.X509Certificates.X509Certificate(filePath, "123456"); //将证书添加客户端证书集合
svc.ClientCertificates.Add(cert); //webservice调用代码...

测试调用报错:请求被中止: 未能创建 SSL/TLS 安全通道,于是赶紧google,找到如下解决方案:

在webservice代理类的构造函数中添加下面的代码,绕过服务器证书验证。

public static bool CheckValidationResult(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
} public SvcService()
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); this.Url = ConfigurationManager.AppSettings["host"];
}

本地vs环境下再试,好了!调用成功!不报错了!于是赶紧发布到IIS服务器上试一下,郁闷的是服务器上居然报错,还是这个未能创建 SSL/TLS 安全通道!

于是继续google,找到下面的解决方法:

1.将客户端证书文件导入到本地计算机账户下的个人存储区。

2.下载winhttpcertcfg.exe 这个工具,下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=19801

3.安装后一般是在C:\Program Files\Windows Resource Kits\Tools这个路径下面。 进入cmd 执行如下命令:winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "test" -a "NetworkService"

这里解释一下这几个参数的含义:

-g 是grant授权的意思,将该证书的使用权限授予某个用户

-c 是certstore证书存储区,指定 本地计算机/当前用户下的证书存储区位置,我们这里是MY,个人存储区

-s 是subjectstr 用于模糊匹配证书的一个字符串,我们这里用证书文件名 test

-a 是account要授权的用户帐号

这里要注意的是授权账户,IIS6下面一般用的是NetworkService,如果你用的IIS7,必须要保证你网站所用的应用程序池的 "标识"和要授权的账户一致。

执行成功之后,会列出模糊匹配出的证书列表和已经授权的账户。

然后程序代码做如下更改:

//webservice客户端代理类
SvcService svc = new SvcService();
//打开本地计算机下的个人证书存储区
X509Store certStore = new System.Security.Cryptography.X509Certificates.X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);
//根据名称查找匹配的证书集合,这里注意最后一个参数,传true的话会找不到
X509Certificate2Collection certCollection = certStore.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "test", false);
//将证书添加至客户端证书集合
svc.ClientCertificates.Add(certCollection[0]); //webservice调用代码

再测试了一下,调用正常!至此这个问题算圆满解决了!
总结:我们导入的客户端证书并不是所有的账户都能访问和使用,因为我们的开发服务器也就是VS自带的服务器默认使用当前用户,而当前用户具有使用证书的权限,所以我们在本地调试的时候,一切正常。当我们将网站部署到IIS后,由于IIS的使用的是内置账户不具有证书的使用权限,所以就出现了上述问题,这个时候我们只需用winhttpcertcfg这个工具给指定账户授予使用证书的权限,就可以正常调用啦!

最新文章

  1. 复星昆仲杨光:VR行业四大痛点
  2. IOS Block-Block块的使用与理解
  3. netcore 控制台中文乱码
  4. top.location.href和localtion.href有什么不同
  5. 避免JS全局变量冲突
  6. ZJOI2008泡泡堂BNB
  7. UIButton图片与文字位置调整
  8. [转]Linux下转换字符集(UTF8转换)
  9. 基于visual Studio2013解决C语言竞赛题之1002字符打印
  10. chrome、safari中的input或textarea
  11. HDU 1863 Kruskal求最小生成树
  12. python专题-Mysql数据库(python2._+ Mysqldb)
  13. RequireJS中的require返回模块
  14. ExtJs radiogroup form.loadRecord方法无法赋值正确解决办法
  15. SpringBoot文件上传(MVC情况和webFlux情况)
  16. WeUI0.6.0有一个Calendar在浏览器下无法直接打开问题
  17. xml添加新节点
  18. Luogu4770 NOI2018你的名字(后缀数组+线段树)
  19. 数据仓库建模与ETL的实践
  20. 一个简单的php分页逻辑

热门文章

  1. 浅谈mysql中不同事务隔离级别下数据的显示效果
  2. libpcap 主要函数及过程详解
  3. 用EPPlus导入导出数据到excel
  4. mac下如何查看指定端口被谁占用并且杀死该进程
  5. python 列表推导的注意点
  6. Python数据结构——散列表
  7. hdu 3591 The trouble of Xiaoqian
  8. JSP中pageEncoding和charset区别,中文乱码解决方案(转载)
  9. ModelState用法
  10. 设置BootStrap导航条的高度