2015-02-06 48 views
3

我正在使用Delphi XE7,在未安裝證書的PC中獲勝8.1。THttpRio https(Wininet)與ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED錯誤信息

我的下一個Web服務https://wsp.hom.orizonbrasil.com.br:6214/tiss/v30200/tissSolicitacaoProcedimento

當我調用Web服務我在Delphi XE7得到此異常: 「證書才能完成客戶端身份驗證 - 網址:https://wsp.hom.orizonbrasil.com.br:6214/tiss/v30200/tissSolicitacaoProcedimento - 的SOAPAction:」」

連接不被擋口,我試圖用SOAPUI(JAVA),並得到了這個Web服務的響應。

我嘗試使用Altova的XML間諜,我也得到類似德爾福XE7錯誤。

爲什麼SoapUI可以工作,而XE7和XML SPY有證書問題?

+0

該webservice正在使用基於證書的身份驗證,您將需要安裝/提供一個Web服務信任的證書。 – whosrdaddy 2015-02-06 10:35:29

+0

請查看[這裏](http://codeverge.com/embarcadero.delphi.webservices/two-way-ssl/1078522)以獲取更多線索。 – whosrdaddy 2015-02-06 10:43:27

+0

儘管我沒有安裝證書,但SoapUI的工作效果很好。當我用SoapUI發送請求時,我有一個答案,它不會抱怨缺少證書。那麼,爲什麼HTTPRio(Delphi)和XML SPY在web服務中遇到需要證書的消息時出現問題呢? Luiz – 2015-02-06 13:06:58

回答

0

很可能,證書位於本地系統的ROOT證書存儲區(受信任的根證書)中。

THTTPRIO不會在Delphi中默認加載這些文件(因此,它找不到正確的文件),而是在當前USER的MY證書存儲區中查找。要強制組件使用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;