忽略控制台应用程序中的Web浏览器SSL安全警报

我正在创建一个能够远程捕获网站截图的控制台应用程序。 一切都在工作,除了我无法避免证书错误。 每次我收到弹出消息,我都无法通过。

我试过用:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

但它不起作用。 还尝试了这里找到的解决方案: http : //www.codeproject.com/Articles/31163/Suppressing-Hosted-WebBrowser-Control-Dialogs但是它似乎不适用于从控制台应用程序调用的webbrowser。

有任何想法吗?

webbrowser控件使用WinInet作为其网络堆栈。 设置ServerCertificateValidationCallback对WinInet没有影响。

要处理证书错误,您需要实现IHttpSecurity服务并根据请求传递给webbrowser。 webbrowser通过ActiveX主机上实现的IServiceProvider查询主机服务。 假设您使用的是Windows窗体,则需要执行以下操作:

  • 从WebBrowser派生一个类
  • 创建一个从WebBrowser.WebBrowserSite派生的嵌套类(您可以从嵌套类派生的唯一方法)
  • 覆盖CreateWebBrowserSiteBase并返回webbrowser站点的新实例。
  • 在webbrowser站点上实现IServiceProvider
  • 实现IServiceProvider.QueryService,以便在请求IHttpSecurity服务时返回IHttpSecurity imepleemntation
  • 处理IHttpSecurity.OnSecurityProblem并返回S_OK
  • 在表单中使用新的webbrowser

示例代码:

public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { if (e.Url.ToString() == "about:blank") { //create a certificate mismatch webBrowser1.Navigate("https://74.125.225.229"); } } } [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 class MyWebBrowser : WebBrowser { public static Guid IID_IHttpSecurity = new Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b"); public static Guid IID_IWindowForBindingUI = new Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b"); public const int S_OK = 0; public const int S_FALSE = 1; public const int E_NOINTERFACE = unchecked((int)0x80004002); public const int RPC_E_RETRY = unchecked((int)0x80010109); protected override WebBrowserSiteBase CreateWebBrowserSiteBase() { return new MyWebBrowserSite(this); } class MyWebBrowserSite : WebBrowserSite, UCOMIServiceProvider, IHttpSecurity, IWindowForBindingUI { private MyWebBrowser myWebBrowser; public MyWebBrowserSite(MyWebBrowser myWebBrowser) :base(myWebBrowser) { this.myWebBrowser = myWebBrowser; } public int QueryService(ref Guid guidService , ref Guid riid , out IntPtr ppvObject) { if (riid ==IID_IHttpSecurity) { ppvObject= Marshal.GetComInterfaceForObject(this , typeof(IHttpSecurity)); return S_OK; } if (riid == IID_IWindowForBindingUI) { ppvObject = Marshal.GetComInterfaceForObject(this , typeof(IWindowForBindingUI)); return S_OK; } ppvObject = IntPtr.Zero; return E_NOINTERFACE; } public int GetWindow(ref Guid rguidReason , ref IntPtr phwnd) { if (rguidReason == IID_IHttpSecurity || rguidReason == IID_IWindowForBindingUI) { phwnd = myWebBrowser.Handle; return S_OK; } else { phwnd = IntPtr.Zero; return S_FALSE; } } public int OnSecurityProblem(uint dwProblem) { //ignore errors //undocumented return code, does not work on IE6 return S_OK; } } } 

终于搞清楚了。

我一直试图绕过作为控制台应用运行的无头IE浏览器的SSL证书错误( http://triflejs.org

ShengJiang提供了大部分答案,但我仍然无法使用Application.Run()因为它锁定主线程上的执行,我需要在循环中执行其他事件,同样,用消息泵实例化ApplicationContext似乎也是复杂。

一旦我得到它,答案非常简单。 只需创建一个循环并运行Application.DoEvents()

这是一些工作代码。 我简化它以适应这里发布的问题。

请确保:

  1. 您正在作为控制台应用程序项目运行。
  2. 您添加项目引用System.Windows.Forms

希望能帮助到你!

 using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace IgnoreSSLErrorBrowserConsoleApp { public class Program { [STAThread] public static void Main(string[] args) { MyWebBrowser browser = new MyWebBrowser(); browser.Navigate("about:blank"); browser.DocumentCompleted += delegate (object obj, WebBrowserDocumentCompletedEventArgs e) { if (e.Url.ToString() == "about:blank") { // This is the SSL path where certificate error occurs browser.Navigate("https://localhost"); } }; while (browser.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); // RunOtherEvents(); } } } [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 class MyWebBrowser : WebBrowser { public static Guid IID_IHttpSecurity = new Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b"); public static Guid IID_IWindowForBindingUI = new Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b"); public const int S_OK = 0; public const int S_FALSE = 1; public const int E_NOINTERFACE = unchecked((int)0x80004002); public const int RPC_E_RETRY = unchecked((int)0x80010109); protected override WebBrowserSiteBase CreateWebBrowserSiteBase() { return new MyWebBrowserSite(this); } class MyWebBrowserSite : WebBrowserSite, UCOMIServiceProvider, IHttpSecurity, IWindowForBindingUI { private MyWebBrowser myWebBrowser; public MyWebBrowserSite(MyWebBrowser myWebBrowser) : base(myWebBrowser) { this.myWebBrowser = myWebBrowser; } public int QueryService(ref Guid guidService , ref Guid riid , out IntPtr ppvObject) { if (riid == IID_IHttpSecurity) { ppvObject = Marshal.GetComInterfaceForObject(this , typeof(IHttpSecurity)); return S_OK; } if (riid == IID_IWindowForBindingUI) { ppvObject = Marshal.GetComInterfaceForObject(this , typeof(IWindowForBindingUI)); return S_OK; } ppvObject = IntPtr.Zero; return E_NOINTERFACE; } public int GetWindow(ref Guid rguidReason , ref IntPtr phwnd) { if (rguidReason == IID_IHttpSecurity || rguidReason == IID_IWindowForBindingUI) { phwnd = myWebBrowser.Handle; return S_OK; } else { phwnd = IntPtr.Zero; return S_FALSE; } } public int OnSecurityProblem(uint dwProblem) { //ignore errors //undocumented return code, does not work on IE6 return S_OK; } } } }