TEmbeddedWB
包含一个事件,用于扩展对其他服务的支持,称为OnQueryService
。根据 MSDN,将调用此函数以允许我返回IHttpSecurity
引用,以便我可以按照自己的方式处理证书错误。但是,虽然OnQueryService
被调用用于许多其他接口,但它永远不会被调用IHttpSecurity
。
示例代码:
unit InsecureBrowser;
interface
uses
Winapi.Windows,
Winapi.Messages,
Winapi.Urlmon,
Winapi.WinInet,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.OleCtrls,
Vcl.StdCtrls,
SHDocVw_EWB,
EwbCore,
EmbeddedWB;
type
TInsecureBrowserForm = class(TForm, IHttpSecurity, IWindowForBindingUI)
web: TEmbeddedWB;
cmdGoInsecure: TButton;
procedure webQueryService(Sender: TObject; const [Ref] rsid,
iid: TGUID; var Obj: IInterface);
procedure cmdGoInsecureClick(Sender: TObject);
private
{ IWindowForBindingUI }
function GetWindow(const guidReason: TGUID; out hwnd): HRESULT; stdcall;
{ IHttpSecurity }
function OnSecurityProblem(dwProblem: Cardinal): HRESULT; stdcall;
end;
var
InsecureBrowserForm: TInsecureBrowserForm;
implementation
{$R *.dfm}
function TInsecureBrowserForm.GetWindow(const guidReason: TGUID;
out hwnd): HRESULT;
begin
Result := S_FALSE;
end;
function TInsecureBrowserForm.OnSecurityProblem(dwProblem: Cardinal): HRESULT;
begin
if (dwProblem = ERROR_INTERNET_INVALID_CA) or
(dwProblem = ERROR_INTERNET_SEC_CERT_CN_INVALID)
then Result := S_OK
else Result := E_ABORT;
end;
procedure TInsecureBrowserForm.webQueryService(Sender: TObject;
const [Ref] rsid, iid: TGUID; var Obj: IInterface);
begin
if IsEqualGUID(IID_IWindowForBindingUI, iid) then
Obj := Self as IWindowForBindingUI
else if IsEqualGUID(IID_IHttpSecurity, iid) then
Obj := Self as IHttpSecurity;
end;
procedure TInsecureBrowserForm.cmdGoInsecureClick(Sender: TObject);
begin
web.Navigate('https://evil.intranet.site');
end;
end.
这并不明显,但事实证明您需要在使用 WebBrowser2
之前导航到about:blank
,或者某些事情不会发生,包括一些QueryService
调用。感谢Igor Tandetnik在2010年发现这一点。
因此,只需添加:
procedure TInsecureBrowserForm.FormCreate(Sender: TObject);
begin
web.Navigate('about:blank');
end;
我也在我的博客上写了这篇文章:https://marc.durdin.net/2016/03/dont-forget-to-navigate-to-aboutblank-when-embedding-iwebbrowser2/