I'm using CEF4Delphi to browse a site, this site asks for a certificate installed on windows, the documentation says I need to select this certificate in the "SelectClientCertificate" event in a callback function passing the index, my question is how to show this certificate window to select one of them
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;
would it be the same window when accessing by firefox or chrome?
I appreciate any help, thanks!
I don't understand where the big deal is: you just display either a Form that you've designed just like any other Form, or you temporarily create one on the fly, just to destroy it again. How you plan to display each certificate (level of detail, fancyness, colors...) is up to you and (of course) works better with a Form already designed.
This is an example with a Form created on the fly:
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;
And this is an example for calling one of your existing Forms:
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;
Using the types/interfaces can't be more straight - just look at their definitions:
TCefX509CertificateArray
is defined in uCEFInterfaces.pas,ICefX509Certificate
and ICefX509CertPrincipal
.TCefTime
is defined in uCEFTypes.pas.