CEF4Delphi 证书选择窗口

问题描述

我正在使用 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 访问时会是同一个窗口吗?

enter image description here

感谢您的帮助,谢谢!

解决方法

我不明白这有什么大不了的:您只是像其他任何表单一样显示您设计的表单,或者您临时临时创建一个表单,只是为了再次销毁它。 您打算如何显示每个证书(细节级别、花哨、颜色...)取决于您,并且(当然)与已经设计的表单一起使用效果更好。

这是一个动态创建的表单示例:

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;

使用类型/接口再简单不过了——看看它们的定义:

  • TCefX509CertificateArrayuCEFInterfaces.pas 中定义,
  • 以及随之而来的所有内容:ICefX509CertificateICefX509CertPrincipal
  • TCefTimeuCEFTypes.pas 中定义。