Perl: Cannot Access Web Service with SSL

て烟熏妆下的殇ゞ 提交于 2019-12-04 04:03:28

问题


This is my first Perl script. I have installed SOAP::Lite using CPAN and it seems to have gone okay.

I'm trying to access a simple HelloWorld .NET web service. I'm getting an error that seems to be related to Perl or SOAP::Lite not being able to verify the SSL certificate.

Although it looks like it's returning a code of 500, I created a Java client that was able to call the web method just fine, so I don't think the problem is on the web service end.

Can anyone point me in the right direction as to how I might get this working?

Script:

#!/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;

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

回答1:


Here is how to make this work securely, i.e. without disabling SSL hostname checking.

If you're talking to a public system with a CA-signed certificate, you need to point LWP to your distribution's root certificate collection. Under a Debian-based system (Ubuntu, etc.), this is kept under /etc/ssl/certs/.

BEGIN {
    $ENV{HTTPS_CA_DIR} = '/etc/ssl/certs'
}

If you are talking to your own server with a self-signed certificate, you can save a copy of that certificate on the client, and point your script to that particular file.

BEGIN {
    $ENV{HTTPS_CA_FILE} = '/path/to/my/server-certificate.crt'
}

You could instead set these in the environment before running your script (e.g. export them from your shell), or you could apply the settings directly to your UserAgent object. See the LWP::UserAgent documentation for more details; search for ssl_opts.




回答2:


$soap->{_transport}->{_proxy}->{ssl_opts}->{verify_hostname} = 0;




回答3:


Just found this thread, and everything was very useful to me, thanks!

I wanted to added my "solution", which is a variation on the previous ones, in case it helps someone else.

Adding

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;

is definitely key. However, this causes a big warning to come out of 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.
*******************************************************************

The way to get rid of that warning was to add these lines:

use IO::Socket::SSL;
IO::Socket::SSL::set_defaults(SSL_verify_mode => "SSL_VERIFY_NONE");

In addition to the original $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}, that should work no matter what client you're using (LWP::UserAgent, RPC::XML::Client, SOAP::Lite, etc.).

Hope that helps someone else!




回答4:


You need to tell LWP to not do hostname checking. For me this only worked using an environment variable, not by setting an option in SOAP::Lite objects:

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;



回答5:


In perl v5.20.2 two things were required for me to disable ssl certificate validation:

Before any SOAP object creation (I've putted it at top)

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;

And then modify SOAP proxy:

my $soap = SOAP::Lite
            -> readable(1)
            -> ns($api_ns, 'tns')
            -> proxy($api_url, ssl_opts => [ SSL_verify_mode => 0 ] )
            -> on_action(sub { return "\"$action\""});



回答6:


As SOAP::Lite repeats LWP calls it should be possible to use

$soap->ssl_opts( verify_hostname => 0 );



回答7:


Or add in your code before calling SOAP method:

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;



回答8:


Boy did this work for me! I threw this into stubmaker.pl and my script which uses the stubmaker.pl output.

IO::Socket::SSL::set_defaults(SSL_verify_mode => "SSL_VERIFY_NONE");
use SOAP::Lite +trace => qw( debug );

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; 


来源:https://stackoverflow.com/questions/14839098/perl-cannot-access-web-service-with-ssl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!