我想用C#重新生成下面的vbscript块。
sURL = "https://server/service.dll"
sXML = "<request version=""1.0""><ticket>generated ticket</ticket></request>"
dim winHTTPReq: Set winHTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
winHttpReq.Open "POST", sURL, false
winHTTPReq.SetRequestHeader "Content-Type", "application/x-some-type"
sCertificate = "LOCAL_MACHINE\MY\Vendor Supplied PFX"
winHTTPReq.SetClientCertificate sCertificate
WinHttpReq.Send(sXML)
....
var xml = (new XElement("request"
, new XElement("ticket", "generated ticket")).ToString();
var cert = X509Certificate.CreateFromCertFile("c:\\Exported Vendor Supplied PFX.cer");
ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
var request = (HttpWebRequest)WebRequest.Create("https://server/service.dll");
request.ClientCertificates.Add(cert);
request.ContentType = "application/x-some-type";
request.Method = "POST";
byte[] bytes = Encoding.UTF8.GetBytes(xml);
request.ContentLength = bytes.Length;
using (var requestStream = request.GetRequestStream())
requestStream.Write(bytes, 0, bytes.Length);
using (var response = (HttpWebResponse)request.GetResponse())
if (response.StatusCode != HttpStatusCode.OK) {
string message = String.Format(
"POST failed. Received HTTP {0}",
response.StatusCode);
throw new ApplicationException(message);
}
我用后一个代码得到了403。我不知道为什么,但我倾向于获得许可。在我可以从cer文件创建证书之前,有什么特别需要的吗?我需要通过winhttpcertcfg应用权限吗?
我最初得到的是一个pfx,它是使用证书MMC导入的。似乎没有办法将pfx添加为客户端证书,因此我将pfx导出为DER x509 cer,以便与CreateFromCertFile()方法一起使用。有办法只使用pfx吗?
[更新]
显然,在磁盘上使用pfx是可能的(只要您有密码),但是[this]http://support.microsoft.com/kb/948154似乎表明,最好依赖证书存储。因为这类似于原始vbscript所做的操作,所以我修改了上面的代码以从存储中提取证书:
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2 cert = store.Certificates.Find(X509FindType.FindBySubjectName
, "XXXX", false)[0];
我添加了通过WinHttpCertCfg工具授予“Everyone”访问证书的权限。仍然没有运气。不幸的是,这也会从服务器返回403。浏览代码时,我可以看到证书正在被找到并成功创建。我还可以验证它是否作为客户端证书添加。不管是什么原因,我只是没有任何运气使用HttpWebResponse。
xml = "<request version=\"1.0\"><ticket>generated ticket</ticket></request>";
var req = new WinHttp.WinHttpRequest();
req.Open("POST", "https://server/service.dll", false);
req.SetRequestHeader("Content-Type", "application/x-some-type");
req.SetClientCertificate(@"LOCAL_MACHINE\MY\Vendor Supplied PFX");
req.Send(xml);
Console.WriteLine(string.Format("{0} {1}", req.Status, req.StatusText));
Console.WriteLine(req.ResponseText);