Скорее всего, сертификат находится в хранилище сертификатов ROOT (доверенных корневых сертификатов) для локальной системы.
THTTPRIO не загружает данные по умолчанию в Delphi (следовательно, он не может найти правильный вариант), вместо этого он выглядит в хранилище 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;
Вебсервис использует аутентификацию на основе сертификата, вам необходимо установить/предоставить сертификат, которому доверяет веб-служба. – whosrdaddy
Пожалуйста, проверьте [здесь] (http://codeverge.com/embarcadero.delphi.webservices/two-way-ssl/1078522) для получения дополнительных сведений. – whosrdaddy
Хотя я не установил сертификат, SoapUI отлично работает. Когда я отправляю запрос с SoapUI, у меня есть ответ, и он не жалуется на отсутствие сертификата. Итак, почему HTTPRio (Delphi) и XML SPY имеют проблемы с webservice с сообщением, требующим сертификата? Luiz –