使用GSoap和SSL时出现问题
我正在针对一个同时具有标准http和https版本的服务编写一个gSoap客户端应用程序。到目前为止,我编写的所有内容都可以与http服务配合使用,但当我切换到https服务时,突然出现了错误 我对https支持代码所做的唯一更改是在启动时添加以下内容:使用GSoap和SSL时出现问题,soap,ssl,openssl,gsoap,Soap,Ssl,Openssl,Gsoap,我正在针对一个同时具有标准http和https版本的服务编写一个gSoap客户端应用程序。到目前为止,我编写的所有内容都可以与http服务配合使用,但当我切换到https服务时,突然出现了错误 我对https支持代码所做的唯一更改是在启动时添加以下内容: soap_ssl_init(); if(soap_ssl_client_context(&_tradeService, SOAP_SSL_SKIP_HOST_CHECK, NULL, NULL, NULL, NULL, NUL
soap_ssl_init();
if(soap_ssl_client_context(&_tradeService, SOAP_SSL_SKIP_HOST_CHECK, NULL, NULL, NULL, NULL, NULL)) {
handleError("Failed to set up SSL connection");
return;
}
如果启用了-DDEBUG
标志,则会得到一个关于证书的错误:“SSL验证错误或证书深度为2的警告:证书链中的自签名证书”,这不会导致soap\u SSL\u客户端\u上下文
返回错误,我不认为这有什么大不了的,因为当我在测试时,我真的不想验证主机
真正的问题是这个错误:
SOAP 1.2故障:SOAP-ENV:发送方[否]
子代码]“无法处理请求
没有有效的操作参数。
请提供有效的soap操作。“
当我尝试向服务提出请求时,我会得到它。如果我查看gsoap生成的发送日志,我会看到outgoing头中设置的SoapAction参数。事实上,如果我比较http/https服务的发送日志,唯一的区别是安全服务的URL以https作为前缀
然后我想可能是服务器出了问题,所以我使用curl发送与gsoap记录它发送的完全相同的XML数据,使用完全相同的头。这很好,我看到了我期望的数据的正常响应。这让我相信可能我设置的SSL不正确
我遇到的另一个问题不在文档中,那就是当我使用-DWITH_OPENSSL-lgsoapssl++-lssl-lcrypto
标志构建时,我仍然收到关于gsoap的ssl方法的链接器错误。为了解决这些问题,我不得不在构建中包含stdsoap2\u ssl\u cpp.cpp,我认为这很奇怪
以前有人试过这样做,可以给我一些建议吗?看起来我们同时也在与类似的问题作斗争 让我先从这个开始: 我遇到的另一个问题不在文档中,那就是当我构建 有了-DWITH_OPENSSL-lgsoapssl++-lssl-lcrypto标志,我仍然感到很高兴 获取有关gsoap的ssl方法的链接器错误。我必须包括 在我的构建中使用stdsoap2_ssl_cpp.cpp来解决这些问题 我觉得很奇怪 仅供参考:我正在使用VirtualBox,Ubuntu 14.04。我使用标志--enable debug和--openssl=/opt/libraries/openssl/build/1.0.1j从源代码处编译了GSOAP2.8.21 如您所见,我还从源代码处编译了openssl,以获取libssl.a和libcrypto.a存档。此外,为了获得libz.a存档,我编译了zlib。在所有这些措施到位后:
- 我使用以下命令从WSDL生成了头文件:
wsdl2h -v -g -o temporary.h https://something.com?wsdl
- 在生成代理类之前,已将此行添加到temporary.h:
#import "wsse.h"
- 用命令生成C++代理客户端类:
soapcpp2 -1 -I/opt/libraries/gsoap/build/2.8.21/share/gsoap/import -C -j temporary.h
- 使用QT Creator(普通项目,不幸的是没有cmake),我的Project.pro文件如下所示:
TEMPLATE = app CONFIG += console CONFIG -= app_bundle CONFIG -= qt QMAKE_CXXFLAGS += -DWITH_OPENSSL QMAKE_CXXFLAGS += -DWITH_DOM QMAKE_CXXFLAGS += -DDEBUG QMAKE_CFLAGS += -DWITH_OPENSSL QMAKE_CFLAGS += -DWITH_DOM QMAKE_CFLAGS += -DDEBUG SOURCES += main.cpp \ soapBasicHttpBinding_USCOREIBarcodeWebServiceProxy.cpp \ soapC.cpp \ ../../../opt/libraries/gsoap/build/2.8.21/share/gsoap/plugin/wsseapi.cpp \ ../../../opt/libraries/gsoap/build/2.8.21/share/gsoap/plugin/mecevp.c \ ../../../opt/libraries/gsoap/build/2.8.21/share/gsoap/plugin/smdevp.c \ HEADERS += \ BasicHttpBinding_USCOREIBarcodeWebService.nsmap \ soapBasicHttpBinding_USCOREIBarcodeWebServiceProxy.h \ soapStub.h \ soapH.h include(deployment.pri) qtcAddDeployment() INCLUDEPATH += ../../../opt/libraries/gsoap/build/2.8.21-debug/share/gsoap unix:!macx: LIBS += -L$$PWD/../../../opt/libraries/gsoap/build/2.8.21-debug/lib/ -lgsoapssl++ INCLUDEPATH += $$PWD/../../../opt/libraries/gsoap/build/2.8.21-debug/include DEPENDPATH += $$PWD/../../../opt/libraries/gsoap/build/2.8.21-debug/include unix:!macx: PRE_TARGETDEPS += $$PWD/../../../opt/libraries/gsoap/build/2.8.21-debug/lib/libgsoapssl++.a unix:!macx: LIBS += -L$$PWD/../../../opt/libraries/openssl/build/1.0.1j/lib/ -lssl INCLUDEPATH += $$PWD/../../../opt/libraries/openssl/build/1.0.1j/include DEPENDPATH += $$PWD/../../../opt/libraries/openssl/build/1.0.1j/include unix:!macx: PRE_TARGETDEPS += $$PWD/../../../opt/libraries/openssl/build/1.0.1j/lib/libssl.a unix:!macx: LIBS += -L$$PWD/../../../opt/libraries/openssl/build/1.0.1j/lib/ -lcrypto INCLUDEPATH += $$PWD/../../../opt/libraries/openssl/build/1.0.1j/include DEPENDPATH += $$PWD/../../../opt/libraries/openssl/build/1.0.1j/include unix:!macx: PRE_TARGETDEPS += $$PWD/../../../opt/libraries/openssl/build/1.0.1j/lib/libcrypto.a unix:!macx: LIBS += -L$$PWD/../../../opt/libraries/zlib/build/1.2.8/lib/ -lz INCLUDEPATH += $$PWD/../../../opt/libraries/zlib/build/1.2.8/include DEPENDPATH += $$PWD/../../../opt/libraries/zlib/build/1.2.8/include unix:!macx: PRE_TARGETDEPS += $$PWD/../../../opt/libraries/zlib/build/1.2.8/lib/libz.a LIBS += -ldl
#include <iostream>
#include "BasicHttpBinding_USCOREIBarcodeWebService.nsmap"
#include "soapBasicHttpBinding_USCOREIBarcodeWebServiceProxy.h"
#include "soapStub.h"
#include "soapH.h"
#include "plugin/wsseapi.h"
回到您的案例,我认为在使用soap_ssl_client_上下文的方法中,其中一个参数还负责设置cacerts.pem位置
如果这仍然不起作用,则始终可以将ssl_标志设置为SOAP_ssl_NO_身份验证
我不知道这是否能解决这个问题:
SOAP 1.2错误:SOAP-ENV:Sender[无子代码]“无法处理请求
没有有效的操作参数。请提供有效的soap操作。“
然而,从gsoap插件附加正确的文件可能会出现这种情况。我在玩SOAP1.1,并禁止为SOAP1.2生成代理客户端类
无论如何,我期待着你的回应。希望我能在第一次与Gsoap打交道时帮你一点忙,避免很多挫折:)
如果启用了-DDEBUG标志,我会得到一个关于证书的错误:“SSL验证错误或证书深度警告2:证书链中的自签名证书”,这不会导致soap\u SSL\u client\u上下文返回错误,我认为这不是什么大问题,因为在测试时,我并不真正关心对主机进行身份验证
当您为生产使用而删除-DDEBUG
时,此错误可能不会消失。您可以通过添加验证回调来接受自签名证书:
soap->fsslverify = verify_callback;
int ssl_verify_callback(int ok, X509_STORE_CTX *store)
{
if (!ok)
{
int err = X509_STORE_CTX_get_error(store);
switch (err)
{
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
X509_STORE_CTX_set_error(store, X509_V_OK);
ok = 1;
break;
}
}
return ok;
}
SOAP 1.2错误:SOAP-ENV:Sender[无子代码]“没有有效的操作参数,无法处理请求。请提供有效的SOAP操作。”
HTTP/S标头中可能缺少SOAP操作,或者由于某些原因不正确。此SOAP操作应该在WSDL中定义,并且特定于调用的每个服务操作
要在HTTP/S标头中设置SOAP操作参数,请确保在进行调用时传递NULL或SOAP操作字符串作为第三个参数:
soap_call_SomeMethod(soap, "endpoint URL", "SOAP Action string", ...);
当传递NULL时,将使用WSDL中定义的SOAP操作字符串。检查wsdl2h生成的代码,了解它所说的内容,以便将服务操作用作SOAP操作。gSOAP服务实际上并不需要SOAP操作,但其他服务(如WCF)会向您抛出错误
使用C++代理对象时,上面调用由简单方法调用代替:
proxy.SomeMethod("endpoint URL", "SOAP Action string", ...);
如果要使用WSDL定义的端点和SOAP操作,请忽略以下参数:
proxy.SomeMethod(...);
就这些
proxy.SomeMethod(...);