简体   繁体   中英

THttpRio https (Wininet) with ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED error message

I am using Delphi XE7, win 8.1 in a PC with no installed certificate.

I have the next Web service https://wsp.hom.orizonbrasil.com.br:6214/tiss/v30200/tissSolicitacaoProcedimento

When I invoke a web service I get this exception in Delphi XE7: "A certificate is required to complete client authentication - URL: https://wsp.hom.orizonbrasil.com.br:6214/tiss/v30200/tissSolicitacaoProcedimento - SOAPAction:""

The connection is not blocked by port as I tried with SOAPUI (java) and got the response from this web service.

I am trying to use Altova xml spy and I get an error similar to delphi XE7.

Why SoapUI works while XE7 and XML SPY have certificate problem?

Most likely, the certificate is in the ROOT certificate store (trusted root certificates) for the local system.

THTTPRIO will not load those by default in Delphi (therefore, it can't find the correct one to use), instead, it looks in the MY certificate store for the current USER. To force the component to use the ROOT certificate store, you have to provide an OnBeforePost so it can open the correct store where the certificate is actually present.

procedure Form1.OnBeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);

const
  CERT_STORE_PROV_SYSTEM_A   = LPCSTR(9);
  CERT_STORE_PROV_SYSTEM_W   = LPCSTR(10);
  {$IFDEF UNICODE}
  CERT_STORE_PROV_SYSTEM     = CERT_STORE_PROV_SYSTEM_W;
  {$ELSE}
  CERT_STORE_PROV_SYSTEM     = CERT_STORE_PROV_SYSTEM_A;
  {$ENDIF}


  CERT_STORE_NO_CRYPT_RELEASE_FLAG            = $00000001;
  CERT_STORE_SET_LOCALIZED_NAME_FLAG          = $00000002;
  CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = $00000004;
  CERT_STORE_DELETE_FLAG                      = $00000010;
  CERT_STORE_MANIFOLD_FLAG                    = $00000100;
  CERT_STORE_ENUM_ARCHIVED_FLAG               = $00000200;
  CERT_STORE_UPDATE_KEYID_FLAG                = $00000400;
  CERT_STORE_READONLY_FLAG                    = $00008000;
  CERT_STORE_OPEN_EXISTING_FLAG               = $00004000;
  CERT_STORE_CREATE_NEW_FLAG                  = $00002000;
  CERT_STORE_MAXIMUM_ALLOWED_FLAG             = $00001000;

  CERT_SYSTEM_STORE_CURRENT_USER_ID  = 1;
  CERT_SYSTEM_STORE_LOCAL_MACHINE_ID = 2;
  CERT_SYSTEM_STORE_LOCATION_SHIFT   = 16;

  CERT_SYSTEM_STORE_CURRENT_SERVICE_ID  = 4;
  CERT_SYSTEM_STORE_SERVICES_ID         = 5;
  CERT_SYSTEM_STORE_USERS_ID            = 6;

  CERT_SYSTEM_STORE_CURRENT_USER    = CERT_SYSTEM_STORE_CURRENT_USER_ID shl CERT_SYSTEM_STORE_LOCATION_SHIFT;
  CERT_SYSTEM_STORE_LOCAL_MACHINE   = CERT_SYSTEM_STORE_LOCAL_MACHINE_ID shl CERT_SYSTEM_STORE_LOCATION_SHIFT;
  CERT_SYSTEM_STORE_CURRENT_SERVICE = CERT_SYSTEM_STORE_CURRENT_SERVICE_ID shl CERT_SYSTEM_STORE_LOCATION_SHIFT;
  CERT_SYSTEM_STORE_SERVICES        = CERT_SYSTEM_STORE_SERVICES_ID shl CERT_SYSTEM_STORE_LOCATION_SHIFT;
  CERT_SYSTEM_STORE_USERS           = CERT_SYSTEM_STORE_USERS_ID shl CERT_SYSTEM_STORE_LOCATION_SHIFT;

  {$IFDEF UNICODE}
  CERT_STORE:PWChar = 'Root';
  {$ELSE}
  CERT_STORE:PAnsiChar = 'Root';
  {$ENDIF}

var
  HTTPRStore: IClientCertInfo;
  hStore: pointer;
  Flags: cardinal;

begin
  HTTPReqResp.InvokeOptions:=[soPickFirstClientCertificate,soIgnoreInvalidCerts];

  if UseSystemCertStore
    then
      begin
        Flags:=CERT_STORE_OPEN_EXISTING_FLAG or CERT_STORE_READONLY_FLAG or CERT_SYSTEM_STORE_LOCAL_MACHINE or CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG;
        HTTPRStore:=HTTPReqResp as IClientCertInfo;
        try
          hStore:=CertOpenStore(CERT_STORE_PROV_SYSTEM,
            0,
            0,
            Flags,
            CERT_STORE);
          HTTPRStore.SetCertStore(hStore);
        finally
          HTTPRStore:=nil;
        end;
      end;
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM