使用GSoap和SSL时出现问题

使用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

我正在针对一个同时具有标准http和https版本的服务编写一个gSoap客户端应用程序。到目前为止,我编写的所有内容都可以与http服务配合使用,但当我切换到https服务时,突然出现了错误

我对https支持代码所做的唯一更改是在启动时添加以下内容:

 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
    
现在回答你问题的第一部分,我认为以下指南应该解决你目前面临的问题:

仅供参考:在main.cpp文件中,我包括:

#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(...);