}
deletetSayHelloSender.args0;
}
soap_destroy(&tClientSoap);
soap_end(&tClientSoap);
soap_done(&tClientSoap);
return0;
}
清单5.支持https方式的C客户端源码
#include"soapH.h"
#include"SimpleServiceSoap11Binding.nsmap"
intmain()
{
structsoaptClientSoap;
struct_ns1__sayHellotSayHelloSender;
struct_ns1__sayHelloResponsetSayHelloResponse;
charachName[256]="thebeautifulworld!
\n";
intiResult;
soap_init(&tClientSoap);
if(soap_ssl_client_context(&tClientSoap,
SOAP_SSL_NO_AUTHENTICATION,
NULL,NULL,NULL,NULL,NULL))
{
soap_print_fault(&tClientSoap,stderr);
return-1;
}
else
{
tSayHelloSender.args0=achName;
iResult=soap_call___ns2__sayHello(&tClientSoap,NULL,NULL,
&tSayHelloSender,&tSayHelloResponse);
if(iResult==SOAP_OK)
{
printf("%s\n",tSayHelloResponse.return_);
}
else
{
printf("Errorcode%d\n",iResult);
}
}
soap_destroy(&tClientSoap);
soap_end(&tClientSoap);
soap_done(&tClientSoap);
return0;
}
通过双向证书认证访问由tomcat7和Axis2搭建的web服务(下)(4)
摘要:
Windows平台下的编译和运行Windows平台下以清单4的C++代码的编译为例。
使用CodeBlocks+MinGW编译的步骤为:
在工程标签上右键选择BuildOption找到Comp
原文出自【风信网】,转载请保留原文链接:
Windows平台下的编译和运行
Windows平台下以清单4的C++代码的编译为例。
使用CodeBlocks+MinGW编译的步骤为:
•在工程标签上右键选择BuildOption
•找到Compilersettings标签下的#defines标签,加入宏WITH_OPENSSL(没有这个宏定义,编译器不会编译soap_ssl_client_context()函数)
•找到Linkersettings标签,添加上MinGW自带的libws2_32.a库文件(没有这个文件会出现找不到sendto()等函数的问题)
•依然是Linkersettings标签,添加上\lib下的libeay32.lib和ssleay32.lib
•找到Searchdirectories标签下的Compiler标签,添加上\include(不是\include\openssl,因为stdsoap2.h文件包含头文件的时候已经将openssl子目录考虑进去了)
•再将\bin目录下libeay32.dll和libeay32.dll拷贝到将生成可执行文件的路径下。
使用VisualStudio2010编译的步骤为:
•在工程标签上右键选择属性
•在属性页面的“C/C++-->预处理器-->预处理器定义”中添加上WITH_OPENSSL(没有这个宏定义,编译器不会编译soap_ssl_client_context()函数)
•在属性页面的“链接器-->输入-->附加依赖项”中添加上\lib下的libeay32.lib和ssleay32.lib
•在属性页面的“VC++目录-->包含目录”中添加上\include(不是\include\openssl,因为stdsoap2.h文件包含头文件的时候已经将openssl子目录考虑进去了)
•再将\bin目录下libeay32.dll和libeay32.dll拷贝到将生成可执行文件的路径下。
注意!
上述的步骤完毕后,编译并运行,可能会有如图9所示的错误
图9.URL不正确引发的错误
引发这个问题的原因是生成的soapClient.cpp文件中定义的用于调用web服务的函数里,默认的URL开头多了一个空格,如图10所示:
图10.URL开头多了个空格
解决的方法,要么手动删除这个空格,要么在清单4中直接把以字符串形式作为调用web服务的函数(本文中为soap_call___ns2__sayHello()函数)的第二个参数传入。
上述问题解决后,再次编译和运行就应该能够看到输出结果“Hello,thebeautifulworld!
”
Linux平台下的编译和运行
Linux平台下以清单5的C代码为例。
输入编译命令:
gcc-oHellos-DWITH_OPENSSL-lcrypto-lssl*.c
即可生成可执行文件。
这里同样要注意图10所说到的URL头部多了一个空格的问题。
编译和运行没有其它问题的话,就应该能够看到输出结果“Hello,thebeautifulworld!
”
通过双向证书认证访问由tomcat7和Axis2搭建的web服务(下)(5)
摘要:
基于证书认证的web服务前面描述了搭建支持https的web服务及访问的方法,但是客户端和服务端之间的通信并没有涉及到证书的认证,接下来我们将要描
原文出自【风信网】,转载请保留原文链接:
基于证书认证的web服务
前面描述了搭建支持https的web服务及访问的方法,但是客户端和服务端之间的通信并没有涉及到证书的认证,接下来我们将要描述如何进行基于证书认证的通信。
关于soap_ssl_client_context()函数
在清单4和清单5中,我们都使用到了soap_ssl_client_context()函数,这个函数的定义位于stdsoap2.cpp或stdsoap2.c中,函数原型为:
intSOAP_FMAC2soap_ssl_client_context(structsoap*soap,
unsignedshortflags,
constchar*keyfile,
constchar*password,
constchar*cafile,
constchar*capath,
constchar*randfile)
在gSOAP网站的UserGuide页面可以找到若干处对该函数各个入参注释的片段,大致的含义如下:
structsoap*soap——用于soap通信的结构指针
unsignedshortflags——是否进行证书认证的标志
constchar*keyfile——如果服务端要认证客户端,填写客户端的“证书+key”拼接文件名
constchar*password——如果服务端要认证客户端,填写客户端的key文件的密码
constchar*cafile——如果客户端要认证服务端,填写CA证书文件名(要包含路径)
constchar*capath——如果客户端要认证服务端,填写CA路径或NULL(本文都用NULL)
constchar*randfile——如果认证过程需要随机文件,填写随机文件名,否则填写NULL
其中第二个表示认证标志的参数,常用的宏定义位于stdsoap2.h中,如图11所示:
图11.gSOAP证书认证宏定义
之前我们用的SOAP_SSL_NO_AUTHENTICATION只是供测试使用,不会进行证书的认证,下文中我们将使用SOAP_SSL_DEFAULT参数。
客户端验证服务端证书
服务端tomcat7保持图4所述的配置不变。
简单的修改soap_ssl_client_context()中的参数即可,修改后的代码片段,如清单6所示,其中,ca.crt文件就是前文所述的CA根证书。
清单6.客户端验证服务端证书代码
if(soap_ssl_client_context(&tClientSoap,SOAP_SSL_DEFAULT,
NULL,NULL,"D:
\\certs\\ca.crt",NULL,NULL))
{
soap_print_fault(&tClientSoap,stderr);
return-1;
}
注意!
前文曾说过,如果服务端证书详细信息中的CommonName(名字与姓氏)与客户端访问的URL的域名或IP地址不一致(例如,证书中填写的是“localhost”,客户端访问时使用的中是“127.0.0.1”),会导致访问失败。
具体报错的代码片段,可以在stdsoap2.cpp或stdsoap2.c中的tcp_connect()函数里找到,如图12所示:
图12.证书信息与URL不一致的检查
由于图12所示的错误提示并不打印在标准输出(通常是屏幕)上,所以一旦出错,客户端程序最多在具体调用web服务的函数(本文中为soap_call___ns2__sayHello()函数)处返回错误码为30的打印(SOAP_SSL_ERROR),难以直接看出原因,所以要特别注意。
编译方法同前文。
如果没什么问题,运行应该能够看到输出结果“Hello,thebeautifulworld!
”
服务端验证客户端证书
服务端tomcat的配置文件需要在图4的配置基础上修改,修改后的配置片段见图13:
图13.服务端验证客户端证书的配置
这里我们加上了truststoreFile和truststorePass字段,并把clientAuth的值改为了true。
修改后记得重启tomcat7服务。
注意!
本例中trustoreFile和keystoreFile配置成同一个keystore文件了,这是因为keystore可以根据别名(alias)存放多份密钥与证书。
完全可以将CA证书导入另一个单独的keystore文件里,作为truststoreFile的参数。
客户端的代码需要在清单6的基础上继续修改,见清单7。
这里,假定client.pem文件中包含的key文件的保护口令是“client”。
清单7.服务端验证客户端证书代码
if(soap_ssl_client_context(&tClientSoap,SOAP_SSL_DEFAULT,
"D:
\\certs\\client.pem","client",
"D:
\\certs\\ca.crt",NULL,NULL))
{
soap_print_fault(&tClientSoap,stderr);
return-1;
}
编译方法同前文。
如果没什么问题,运行应该能够看到输出结果“Hello,thebeautifulworld!
”