这是我的第一个Perl脚本。我已经使用CPAN安装了SOAP :: Lite,它似乎没问题。
我正在尝试访问一个简单的HelloWorld .NET Web服务。我收到的错误似乎与Perl或SOAP :: Lite无法验证SSL证书有关。
虽然它看起来像是返回500的代码,但是我创建了一个能够很好地调用web方法的Java客户端,所以我认为问题不在Web服务端。
任何人都可以指出我的方向是正确的吗?
#!/usr/bin/perl
use SOAP::Lite 'trace', 'debug';
$api_ns = "https://www.mydomain.com/edgedev/";
$api_url = "https://www.mydomain.com/edgedev/ws.asmx";
$action = "HelloWorld";
my $soap = SOAP::Lite
-> readable(1)
-> ns($api_ns, 'tns')
-> proxy($api_url)
-> on_action(sub { return "\"$action\""});
print $soap->HelloWorld()->result;
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="https://www.mydomain.com/edgedev/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<tns:HelloWorld xsi:nil="true" />
</soap:Body>
</soap:Envelope>
SOAP::Transport::HTTP::Client::send_receive: 500 Can't connect to www.mydomain.com:443 (certificate verify failed)
Content-Type: text/plain
Client-Date: Tue, 12 Feb 2013 16:40:28 GMT
Client-Warning: Internal response
Can't connect to www.mydomain.com:443 (certificate verify failed)
You can disable hostname check by setting environment variable PERL_LWP_SSL_VERIFY_HOSTNAME=0
LWP::Protocol::https::Socket: SSL connect attempt failed with unknown errorerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed at /usr/lib/perl5/vendor_perl/5.10.0/LWP/Protocol/http.pm line 57.
500 Can't connect to www.mydomain.com:443 (certificate verify failed) at ./soaptest.pl line 15
答案 0 :(得分:7)
以下是如何安全地进行此操作,即不禁用SSL主机名检查。
如果您正在与具有CA签名证书的公共系统进行通信,则需要将LWP指向您的发行版的根证书集合。在基于Debian的系统(Ubuntu等)下,它保存在/etc/ssl/certs/
下。
BEGIN {
$ENV{HTTPS_CA_DIR} = '/etc/ssl/certs'
}
如果您使用自签名证书与自己的服务器通信,则可以在客户端上保存该证书的副本,并将脚本指向该特定文件。
BEGIN {
$ENV{HTTPS_CA_FILE} = '/path/to/my/server-certificate.crt'
}
您可以在运行脚本之前在环境中设置它们(例如,从shell中导出它们),或者可以将设置直接应用于UserAgent对象。有关详细信息,请参阅LWP::UserAgent documentation;搜索ssl_opts
。
答案 1 :(得分:3)
$soap->{_transport}->{_proxy}->{ssl_opts}->{verify_hostname} = 0;
答案 2 :(得分:1)
您需要告诉LWP不要进行主机名检查。对我来说,这只能使用环境变量,而不是在SOAP :: Lite对象中设置选项:
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
答案 3 :(得分:1)
在perl v5.20.2中,我需要两件事来禁用ssl证书验证:
在创建任何SOAP对象之前(我把它放在顶部)
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
然后修改SOAP代理:
my $soap = SOAP::Lite
-> readable(1)
-> ns($api_ns, 'tns')
-> proxy($api_url, ssl_opts => [ SSL_verify_mode => 0 ] )
-> on_action(sub { return "\"$action\""});
答案 4 :(得分:1)
刚刚找到这个帖子,对我来说一切都非常有用,谢谢!
我想添加我的&#34;解决方案&#34;,这是以前版本的变体,以防它帮助其他人。
添加
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
绝对是关键。但是,这会导致大警告来自IO::Socket::SLL
:
*******************************************************************
Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
is deprecated! Please set SSL_verify_mode to SSL_VERIFY_PEER
together with SSL_ca_file|SSL_ca_path for verification.
If you really don't want to verify the certificate and keep the
connection open to Man-In-The-Middle attacks please set
SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
*******************************************************************
摆脱这种警告的方法是添加以下几行:
use IO::Socket::SSL;
IO::Socket::SSL::set_defaults(SSL_verify_mode => "SSL_VERIFY_NONE");
除了原始的$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}
之外,无论您使用哪个客户端(LWP::UserAgent
,RPC::XML::Client
,SOAP::Lite
等),这都应该有效。
希望能帮到别人!
答案 5 :(得分:0)
当SOAP :: Lite重复LWP调用时,应该可以使用
$soap->ssl_opts( verify_hostname => 0 );
答案 6 :(得分:0)
或者在调用SOAP方法之前添加代码:
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
答案 7 :(得分:0)
男孩为我做了这项工作! 我把它扔进了stubmaker.pl和我使用stubmaker.pl输出的脚本。
IO::Socket::SSL::set_defaults(SSL_verify_mode => "SSL_VERIFY_NONE");
use SOAP::Lite +trace => qw( debug );
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;