web-services - 带有 ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED 错误消息的 THttpRio https (Wininet)

标签 web-services delphi ssl delphi-xe7

我使用的是 Delphi XE7,在未安装证书的 PC 上运行 8.1。

我有下一个 Web 服务 https://wsp.hom.orizonbrasil.com.br:6214/tiss/v30200/tissSolicitacaoProcedimento

当我调用 Web 服务时,我在 Delphi XE7 中遇到了这个异常: “需要证书才能完成客户端身份验证 - URL:https://wsp.hom.orizonbrasil.com.br:6214/tiss/v30200/tissSolicitacaoProcedimento - SOAPAction:”“

当我尝试使用 SOAPUI (java) 并从该 Web 服务获得响应时,连接未被端口阻止。

我正在尝试使用 Altova xml spy,但出现类似于 delphi XE7 的错误。

为什么 SoapUI 可以工作,而 XE7 和 XML SPY 有证书问题?

最佳答案

很可能,该证书位于本地系统的 ROOT 证书库(受信任的根证书)中。

THTTPRIO 不会在 Delphi 中默认加载这些证书(因此,它找不到要使用的正确证书),而是在 MY 证书库中查找当前 USER。要强制组件使用 ROOT 证书存储,您必须提供一个 OnBeforePost,以便它可以打开证书实际存在的正确存储。

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;

关于web-services - 带有 ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED 错误消息的 THttpRio https (Wininet),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28363065/

相关文章:

android - Android 中的 Web 服务 SOAP

java.io.FileNotFoundException : while accessing REST service 错误

multithreading - Delphi 当应用程序在线程等待事件时终止时会发生什么?

python - 如果 SSL Labs 显示 "This server' 的证书链不完整,证书握手能否完成。等级上限为B。”?

sockets - 关闭套接字 FD 后 SSL session 恢复

asp.net-mvc - ASP.NET MVC : How to automatically disable [RequireHttps] on localhost?

node.js - Swagger - Swagger 规范中定义的路由,但没有定义 get 操作

web-services - Jetty Webservice - 不支持基于 https 协议(protocol)的地址

delphi - 对于在同一类中设置全局变量的例程,什么是好的命名约定

delphi - 有没有关于 turbopower 的 OnGuard 的文档?