问题描述
我正在使用 CEF4Delphi 浏览站点,该站点要求安装在 Windows 上的证书,文档说我需要在传递索引的回调函数中的“SelectClientCertificate”事件中选择此证书,我的问题是如何显示此证书窗口以选择其中之一
procedure TFPrin.WebBCSelectClientCertificate(Sender: TObject;
const browser: ICefbrowser; isProxy: Boolean; const host: ustring;
port: Integer; certificatesCount: NativeUInt;
const certificates: TCefX509CertificateArray;
const callback: ICefSelectClientCertificateCallback; var aResult: Boolean);
begin
aresult:=true;
//show certificate window here?
callback.Select(certificates[Certindex]);
end;
firefox 或 chrome 访问时会是同一个窗口吗?
感谢您的帮助,谢谢!
解决方法
我不明白这有什么大不了的:您只是像其他任何表单一样显示您设计的表单,或者您临时临时创建一个表单,只是为了再次销毁它。 您打算如何显示每个证书(细节级别、花哨、颜色...)取决于您,并且(当然)与已经设计的表单一起使用效果更好。
这是一个动态创建的表单示例:
procedure TFPrin.Chromium1SelectClientCertificate
( Sender: TObject
; const browser: ICefBrowser
; isProxy: Boolean
; const host: uCEFTypes.ustring
; port: Integer
; certificatesCount: Cardinal
; const certificates: TCefX509CertificateArray
; const callback: ICefSelectClientCertificateCallback
; var aResult: Boolean
);
var
iCert: Integer; // Which certificate we're just analyzing
sLine: String; // Information about the current certificate
frm: TForm; // Displayed (temporary) modal window
lbx: TListBox; // All certificates to choose from
pan: TPanel; // For the buttons
// Converting a certificate time
function _TimeToStr( vTime: TCefTime ): String;
begin
result:= IntToStr( vTime.year )+ '-'
+ IntToStr( vTime.month )+ '-'
+ IntToStr( vTime.day_of_month );
end;
begin
// Create temporary form...
frm:= TForm.Create( Application );
with frm do begin
try
BorderStyle:= bsSizeable;
// ...along with its temporary controls:
// Bottom panel,which will contain both buttons
pan:= TPanel.Create( frm );
with pan do begin
Parent:= frm;
Align:= alBottom;
Height:= 30;
end;
// Buttons that automatically set the form's modal result
with TButton.Create( frm ) do begin
Parent:= pan;
Caption:= '&Ok';
ModalResult:= ID_OK;
Default:= True; // We can press ENTER anywhere to trigger this button
Top:= 3;
Left:= 10;
end;
with TButton.Create( frm ) do begin
Parent:= pan;
Caption:= '&Cancel';
ModalResult:= ID_CANCEL;
Cancel:= True; // We can press ESC anywhere to trigger this button
Top:= 3;
Left:= 100;
end;
// A list displaying one certificate per line to choose from
lbx:= TListBox.Create( frm );
with lbx do begin
Parent:= frm;
Align:= alClient;
end;
// Now going thru all certificate details and adding each resulting text line to the listbox
for iCert:= Low( certificates ) to High( certificates ) do begin
sLine:= 'Subject: '+ certificates[iCert].GetSubject().GetDisplayName()+ '. '
+ 'Issuer: '+ certificates[iCert].GetIssuer().GetDisplayName()+ '. '
+ 'Valid from '+ _TimeToStr( certificates[iCert].GetValidStart() )+ ' to '
+ _TimeToStr( certificates[iCert].GetValidExpiry() )+ '.';
lbx.Items.Add( sLine );
end;
if lbx.Count> 0 then lbx.ItemIndex:= 0; // Pre-select first certificate
// Display the form and check if the "Ok" button has been pressed and a line is selected.
// If yes,actually choose a certificate.
aResult:= (ShowModal()= ID_OK) and (lbx.ItemIndex<> -1);
if aResult then callback.Select( certificates[lbx.ItemIndex] );
finally
// Free temporary form and all its controls
frm.Free;
end;
end;
end;
这是调用现有表单之一的示例:
uses
frmOther;
procedure TFPrin.Chromium1SelectClientCertificate
...
var
iCert: Integer; // Which certificate we're just analyzing
sLine: String; // Information about the current certificate
// Converting a certificate time
function _TimeToStr( vTime: TCefTime ): String;
begin
result:= IntToStr( vTime.year )+ '-'
+ IntToStr( vTime.month )+ '-'
+ IntToStr( vTime.day_of_month );
end;
begin
// Remove any existing entries in TFOther
FOther.lbxCert.Clear();
// Now going thru all certificate details and adding each resulting text line to the listbox
for iCert:= Low( certificates ) to High( certificates ) do begin
sLine:= 'Subject: '+ certificates[iCert].GetSubject().GetDisplayName()+ '. '
+ 'Issuer: '+ certificates[iCert].GetIssuer().GetDisplayName()+ '. '
+ 'Valid from '+ _TimeToStr( certificates[iCert].GetValidStart() )+ ' to '
+ _TimeToStr( certificates[iCert].GetValidExpiry() )+ '.';
FOther.lbxCert.Items.Add( sLine );
end;
if FOther.lbxCert.Count> 0 then FOther.lbxCert.ItemIndex:= 0; // Pre-select first certificate
// Display the form and check if the "Ok" button has been pressed and a line is selected.
// If yes,actually choose a certificate.
aResult:= (FOther.ShowModal()= ID_OK) and (FOther.lbxCert.ItemIndex<> -1);
if aResult then callback.Select( certificates[FOther.lbxCert.ItemIndex] );
end;
使用类型/接口再简单不过了——看看它们的定义:
-
TCefX509CertificateArray
在 uCEFInterfaces.pas 中定义, - 以及随之而来的所有内容:
ICefX509Certificate
和ICefX509CertPrincipal
。 -
TCefTime
在 uCEFTypes.pas 中定义。