C#Webbrowser:以编程方式定义要使用的证书
我一直在开发一项服务,该服务连接到一台服务器,该服务器使用数字签名以验证用户身份访问页面。为了能够连接到该网页并使用它,我使用了“WebBrowser”()类 实际上,当到达网页时,会弹出此窗口,选择我电脑中的一个可能证书来识别我自己: 为了解决这个问题,我一直在网上搜索,找到了不同的潜在解决方案,但没有一个能很好地解决这个问题 为了能够解决这个问题,我在类中包含了下一个代码,以便能够捕获来自WebBrowser的函数调用:C#Webbrowser:以编程方式定义要使用的证书,c#,internet-explorer,browser,certificate,programmatically,C#,Internet Explorer,Browser,Certificate,Programmatically,我一直在开发一项服务,该服务连接到一台服务器,该服务器使用数字签名以验证用户身份访问页面。为了能够连接到该网页并使用它,我使用了“WebBrowser”()类 实际上,当到达网页时,会弹出此窗口,选择我电脑中的一个可能证书来识别我自己: 为了解决这个问题,我一直在网上搜索,找到了不同的潜在解决方案,但没有一个能很好地解决这个问题 为了能够解决这个问题,我在类中包含了下一个代码,以便能够捕获来自WebBrowser的函数调用: [Guid("6D5140C1-7436-11CE-8034
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface UCOMIServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(
[In] ref Guid guidService,
[In] ref Guid riid,
[Out] out IntPtr ppvObject);
}
[ComImport()]
[ComVisible(true)]
[Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IWindowForBindingUI
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetWindow(
[In] ref Guid rguidReason,
[In, Out] ref IntPtr phwnd);
}
[ComImport()]
[ComVisible(true)]
[Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IHttpSecurity
{
//derived from IWindowForBindingUI
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetWindow(
[In] ref Guid rguidReason,
[In, Out] ref IntPtr phwnd);
[PreserveSig]
int OnSecurityProblem(
[In, MarshalAs(UnmanagedType.U4)] uint dwProblem);
}
以及一个能够知道何时出现问题并尝试解决问题的函数:
public int OnSecurityProblem(uint dwProblem)
{
int dwCertSelection2 = 2;
IntPtr dwCertSelection = new IntPtr(dwCertSelection2);
//ignore errors
//undocumented return code, does not work on IE6
if (dwProblem == 12044)
{
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2 x509 = fcollection[2];
IntPtr unmanagedPointer = Marshal.AllocHGlobal(x509.RawData.Length);
Marshal.Copy(x509.RawData, 0, unmanagedPointer, x509.RawData.Length);
bool VF_Resultado = WinHttpSetOption(this.myWebBrowser.Handle, 47, unmanagedPointer, x509.RawData.Length);
Marshal.FreeHGlobal(unmanagedPointer);
store.Close();
return RPC_E_RETRY;
}
return S_OK;
}
要进一步澄清,请执行以下操作:
如果(dwProblem==12044)--->//12044,则需要错误\u INTERNET\u CLIENT\u AUTH\u CERT\u。这表明我们需要通过认证
bool VF_Resultado=WinHttpSetOption(this.myWebBrowser.Handle,47,非托管指针,x509.RawData.Length);-->//INTERNET\u选项\u安全性\u选择\u客户端\u证书47,理论上,通过此功能,我们可以指示我们想要使用的证书,而无需选择它
此代码基于不同的源代码(我尝试了这两种解决方案,但没有成功):
问题是这段代码没有达到预期的效果,我对能否确保它正常工作有各种疑问:
谢谢您经过多次测试和审查,我得出结论,使用webBrowser控件不可能做到这一点,这是因为必须使用此功能才能通过认证:
WinHttpSetOption(this.myWebBrowser.Handle, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, dwCertSelection, size)
这里的主要问题是WinHttpSetOption需要在调用函数“HttpOpenRequest”后返回处理程序会话:
无法从C#WebBrowser对象获取的数据。感谢您发布此问题的解决方案。您可以将您的答案标记为已接受的答案。它可以在将来帮助其他社区成员解决类似的问题。谢谢你的理解。