我想使用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)
....
我所做的所有尝试都是a)无功能,b)比上面的片段长一点。
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申请权限吗?
我最初获得了使用证书MMC导入的pfx。似乎没有办法将pfx添加为客户端证书,因此我将pfx导出为DER x509 cer,以便与CreateFromCertFile()方法一起使用。有没有办法只使用pfx?
当然,最初的VBScript运行正常 - 我只是想知道转换它需要什么。它似乎并不太难,但到目前为止,我有一段艰难的时光。
[更新]
显然可以在磁盘上使用pfx(只要你有密码)但是[这个] 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。
但是,使用interop工作正常。尽管我不喜欢依赖于非本机框架的东西,但WinHttpRequest组件似乎更容易使用。我可以用大约1/4的代码完成同样的事情,这与应用程序的其余部分很好地集成。
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);