git-cpan-module: SOAP-WSDL git-cpan-version: 2.00.10 git-cpan-authorid: MKUTTER git-cpan-file: authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.10.tar.gz
277 lines
9.0 KiB
INI
277 lines
9.0 KiB
INI
=pod
|
|
|
|
=head1 NAME
|
|
|
|
SOAP::WSDL::Manual::Cookbook - SOAP::WSDL recipes
|
|
|
|
=head2 Accessing HTTPS webservices
|
|
|
|
You need Crypt::SSLeay installed to access HTTPS webservices.
|
|
|
|
=head2 Accessing protected web services
|
|
|
|
Passing a username and password, or a client certificate and key, to the
|
|
transport layer is highly dependent on the transport backend. The descriptions
|
|
below are for HTTP(S) transport using LWP::UserAgent
|
|
|
|
=head3 Accessing HTTP(S) webservices with basic/digest authentication
|
|
|
|
When using SOAP::WSDL::Transport::HTTP (SOAP::Lite not installed), add a
|
|
method called "get_basic_credentials" to SOAP::WSDL::Transport::HTTP:
|
|
|
|
*SOAP::WSDL::Transport::HTTP::get_basic_credentials = sub {
|
|
return ($user, $password);
|
|
};
|
|
|
|
When using SOAP::Transport::HTTP (SOAP::Lite is installed), do the same to
|
|
this backend:
|
|
|
|
*SOAP::Transport::HTTP::Client::get_basic_credentials = sub {
|
|
return ($user, $password);
|
|
};
|
|
|
|
=head3 Accessing HTTP(S) webservices protected by NTLM authentication
|
|
|
|
If you want to connect to a windows server using some Windows Domain Login, please
|
|
consider using Kerberos instead of the (older) NTLM mechanism - see below.
|
|
|
|
Kerberos and NTLM are (currently) mutually exclusive - when LWP::Authen::Negotiate
|
|
is installed, it will always be queried (and will always raise an error), even
|
|
if you don't want to use it. See http://rt.cpan.org/Public/Bug/Display.html?id=32826
|
|
for details.
|
|
|
|
You need the L<NTLM|NTLM> distribution installed to access webservices protected
|
|
by NTLM authentication. More specifically, you need the Authen::NTLM module
|
|
from this distribution. Note that this is different from the Authen::NTML
|
|
distribution by Yee Man Chan also available from CPAN.
|
|
|
|
Your user credentials usually need to include the windows domain or the
|
|
windows hostname like this:
|
|
|
|
testdomain\testuser
|
|
|
|
or
|
|
|
|
\\testhost\testuser
|
|
|
|
Besides passing user credentials as when accessing a web service protected
|
|
by basic or digest authentication, you also need to enforce connection
|
|
keep_alive on the transport backens.
|
|
|
|
To do so, pass a I<proxy> argument to the new() method of the generated
|
|
class. This unfortunately means that you have to set the endpoint URL, too:
|
|
|
|
my $interface = MyInterfaces::SERVICE_NAME::PORT_NAME->new({
|
|
proxy => [ $url, keep_alive => 1 ]
|
|
});
|
|
|
|
You may, of course, decide to just hack the generated class. Be advised that
|
|
subclassing might be a more appropriate solution - re-generating overwrites
|
|
changes in interface classes.
|
|
|
|
=head3 Accessing HTTP(S) webservices protected by NTLMv2
|
|
|
|
There are different variants of NTLM, and by default Authen::NTLM uses the v1 variant.
|
|
|
|
NTLM is a connection-based handshake authentication protocol, which requires
|
|
three or more requests on the same connection:
|
|
|
|
Request POST
|
|
Response 401 Unauthorized
|
|
WWW-Authenticate: NTLM
|
|
|
|
Request Authorization: NTLM <base64-encoded type-1-message>
|
|
Response 401 Unauthorized
|
|
WWW-Authenticate: NTLM <base64-encoded type-2-message>
|
|
|
|
Request Authorization: NTLM <base64-encoded type-3-message>
|
|
Response 200 Ok
|
|
|
|
If you try to access a NTLMv2 protected web service and switch on LWP::Debug by
|
|
saying
|
|
|
|
use LWP::Debug qw(+);
|
|
|
|
you should see at least two lines containing something like
|
|
|
|
Authorization NTLM TlRMTVNTUAABAAAAB7IAAAAAAAAAAAAAAwADACAAAABmb28=
|
|
...
|
|
Authorization NTLM TlRMTVNTUAABAAAAB7IAAAAAAAAAAAAAAw ... much longer ... ADACAAAABmb28=
|
|
|
|
If you're talking to a Server using NTLMv2 exclusively, you will only the first line
|
|
in the debug output, and then an error.
|
|
|
|
To explicitely enable NTLMv2, do the following in your client:
|
|
|
|
use Authen::NTLM;
|
|
ntlmv2(1);
|
|
|
|
This globally enables the use of NTLMv2. Note that this is a global setting: All
|
|
clients running in the same perl interpreter will be affected. This can
|
|
cause unexpected issues when running under mod_perl.
|
|
|
|
=head3 Accessing webservices protected by HTTP Kerberos Authentication
|
|
|
|
Use the L<LWP::Authen::Negotiate|LWP::Authen::Negotiate> plugin from CPAN. You
|
|
need to set up GSSAPI to perform the Kerberos authentication, though. How to do
|
|
this is implementation specific (MIT or Heimdahl). See your Kerberos/GSSAPI
|
|
documentation for details.
|
|
|
|
(Newer) Windows Web Services usually allow to use both the Negotiate (Kerberos)
|
|
and NTLM authentication scheme.
|
|
|
|
=head3 Accessing HTTPS webservices protected by certificate authentication
|
|
|
|
You need Crypt::SSLeay installed to access HTTPS webservices.
|
|
|
|
See L<Crypt::SSLeay> on how to configure client certificate authentication.
|
|
|
|
=head1 XML OUTPUT
|
|
|
|
=head2 Outputting namespaces as prefixes
|
|
|
|
Q: I need to interface with a SOAP server which doesn't accept the following
|
|
format:
|
|
|
|
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
|
<SOAP-ENV:Body>
|
|
<getElement xmlns="http://services.company.com/">
|
|
<elementId>12345</elementId>
|
|
</getElement>
|
|
</SOAP-ENV:Body>
|
|
</SOAP-ENV:Envelope>
|
|
|
|
Instead, it requires this:
|
|
|
|
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns:ns2="http://services.company.com/"
|
|
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
|
<SOAP-ENV:Body>
|
|
<ns2:getElement>
|
|
<ns2:elementId>12345</ns2:elementId>
|
|
</ns2:getElement>
|
|
</SOAP-ENV:Body>
|
|
</SOAP-ENV:Envelope>
|
|
|
|
How do I do this using SOAP::WSDL?
|
|
|
|
A: The following steps are neccessary to achieve this result:
|
|
|
|
First, you would need to write a new serializer, which is quite easy, as it
|
|
just creates the envelope and calls ->serialize_qualified() on $header and
|
|
$body to fill them in. The new serializer has to declare all namespace
|
|
prefixes used, the rest is just the same as the original XSD serializer.
|
|
|
|
Second, you'd need to overwrite the start_tag method in
|
|
L<SOAP::WSDL::XSD::Typelib::Element|SOAP::WSDL::XSD::Typelib::Element> to use
|
|
the appropriate prefixes for the body elements.
|
|
|
|
In contrast to the original method, it would probably look up the appropriate
|
|
prefix from some data set in the serializer class, so this could be the
|
|
appropriate place to load SOAP::WSDL::XSD::Typelib::Element and override the
|
|
method.
|
|
|
|
Something like this should do (without the handling of specialties like empty
|
|
or nil elements):
|
|
|
|
%PREFIX_OF = { 'http://services.company.com/' => 'ns2' };
|
|
|
|
*SOAP::WSDL::XSD::Typelib::Element::start_tag = sub {
|
|
# use prefix instead of xmlns attribute and copy the rest from
|
|
# SOAP::WSDL::XSD::Typelib::Element::start_tag
|
|
my $prefix = $PREFIX_OF{ $_[0]->get_xmlns() };
|
|
my $name = $_[1]->{ name } || $self->__get_name();
|
|
return "<$prefix:$name>";
|
|
}
|
|
|
|
=head1 Skipping unknown XML elements - "lax" XML processing
|
|
|
|
SOAP::WSDL's default serializer
|
|
L<SOAP::WSDL::Deserializer::XSD|SOAP::WSDL::Deserializer::XSD> is a "strict"
|
|
XML processor in the sense that it throws an exception on encountering unknown
|
|
XML elements.
|
|
|
|
L<SOAP::WSDL::Deserializer::XSD|SOAP::WSDL::Deserializer::XSD> allows
|
|
switching off the stric XML processing by passing the C<strict =E<gt> 0>
|
|
option.
|
|
|
|
=head2 Disabling strict XML processing in a Client
|
|
|
|
Pass the following as C<deserializer_args>:
|
|
|
|
{ strict => 0 }
|
|
|
|
Example: The generated SOAP client is assumed to be "MyInterface::Test".
|
|
|
|
use MyInterface::Test;
|
|
|
|
my $soap = MyInterface::Test->new({
|
|
deserializer_args => { strict => 0 }
|
|
});
|
|
|
|
my $result = $soap->SomeMethod();
|
|
|
|
=head2 Disabling strict XML processing in a CGI based server
|
|
|
|
You have to set the deserializer in the transport class explicitely to
|
|
a L<SOAP::WSDL::Deserializer|SOAP::WSDL::Deserializer> object with the
|
|
C<strict> option set to 0.
|
|
|
|
Example: The generated SOAP server is assumed to be "MyServer::Test".
|
|
|
|
use strict;
|
|
use MyServer::Test;
|
|
use SOAP::WSDL::Deserializer::XSD;
|
|
|
|
my $soap = MyServer::Test->new({
|
|
transport_class => 'SOAP::WSDL::Server::CGI',
|
|
dispatch_to => 'main',
|
|
});
|
|
$soap->get_transport()->set_deserializer(
|
|
SOAP::WSDL::Deserializer::XSD->new({ strict => 0 })
|
|
);
|
|
|
|
$soap->handle();
|
|
|
|
=head2 Disabling strict XML processing in a mod_perl based server
|
|
|
|
Sorry, this is not implemented yet - you'll have to write your own handler
|
|
class based on L<SOAP::WSDL::Server::Mod_Perl2|SOAP::WSDL::Server::Mod_Perl2>.
|
|
|
|
=head1 Changing the encoding of a SOAP request
|
|
|
|
SOAP::WSDL uses utf-8 per default: utf-8
|
|
is the de-facto standard for webservice ommunication.
|
|
|
|
However, you can change the encoding the transport layer announces by calling
|
|
C<set_encoding($encoding)> on a client object.
|
|
|
|
You probably have to write your own serializer class too, because the default
|
|
serializer has the utf-8 encoding hardcoded in the envelope.
|
|
|
|
Just look into SOAP::WSDL::Serializer on how to do that.
|
|
|
|
Don't forget to register your serializer at the serializer factory
|
|
SOAP::WSDL::Factory::Serializer.
|
|
|
|
=head1 LICENSE AND COPYRIGHT
|
|
|
|
Copyright 2008, 2009 Martin Kutter.
|
|
|
|
This file is part of SOAP-WSDL. You may distribute/modify it under
|
|
the same terms as perl itself.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
|
|
|
=head1 REPOSITORY INFORMATION
|
|
|
|
$Rev: 583 $
|
|
$LastChangedBy: kutterma $
|
|
$Id: $
|
|
$HeadURL: $
|
|
|
|
=cut
|