perlchild has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to access an NTLM protected web service that is running on a Windows Server 2003 IIS 6 web server. Below is some sample code and the error output that I am getting.

# use strict; use warnings; use LWP::UserAgent; use LWP::Debug; use SOAP::Lite on_action => sub { "$_[0]$_[1]"; }; LWP::Debug::level('+'); SOAP::Lite->import(+trace => 'all'); our $domain = 'MYDOMAIN'; our $username = 'MYDOMAIN\\Username'; our $password = 'password'; our $webserver = ""; our @ua_args = (keep_alive => 1); our @credentials = ($domain, "", $username, $password); our $soap = SOAP::Lite->proxy('https://' . $webserver . '/gsoap/gsoap_ssl.dll?ttwebservices', @ua_args, credentials => \@cred +entials); $soap->uri("urn:ttwebservices"); # call the function for GetVersion our $som = $soap->GetVersion(); print "\n " . $som->valueof('//GetVersionResponse/return') . "\n";

The output is ...

SOAP::Lite::new: () LWP::UserAgent::new: () SOAP::Transport::HTTP::Client::new: () SOAP::Lite::call: () SOAP::Serializer::envelope: () SOAP::Serializer::envelope: GetVersion SOAP::Data::new: () SOAP::Data::new: () SOAP::Data::new: () SOAP::Data::new: () SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x1c96 +d64) SOAP::Transport::HTTP::Client::send_receive: POST +m/gsoap/gsoap_ssl.dll?ttwebservices Accept: text/xml Accept: multipart/* Content-Length: 447 Content-Type: text/xml; charset=utf-8 SOAPAction: urn:ttwebservicesGetVersion <?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:xsi="ht +tp://" xmlns:SOAP-ENC="" xmlns:SOAP- +ENV="" xmlns:xsd="" SOAP-ENV:encodingStyle="h +ttp://"><SOAP-ENV:Body><namesp1:Get +Version xmlns:namesp1="urn:ttwebservices"/></SOAP-ENV:Body></SOAP-ENV:Envelope +> LWP::UserAgent::request: () LWP::UserAgent::send_request: POST +sl.dll?ttwebservices LWP::UserAgent::_need_proxy: Not proxied LWP::Protocol::http::request: () LWP::Protocol::collect: read 758 bytes LWP::Protocol::collect: read 798 bytes LWP::Protocol::collect: read 100 bytes LWP::Protocol::http::request: Keep the http connection to +m:443 LWP::UserAgent::request: Simple response: Unauthorized LWP::Authen::Ntlm::authenticate: authenticate() has been called Use of uninitialized value in exists at c:\Perl\lib/LWP/ l +ine 574. LWP::Authen::Ntlm::authenticate: No username and password available fr +om get_basic_credentials(). Returning unmodified response object SOAP::Transport::HTTP::Client::send_receive: HTTP::Response=HASH(0x1f0 +5e90) SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 401 Unauthorized Date: Tue, 28 Oct 2008 12:37:47 GMT Server: Microsoft-IIS/6.0 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM WWW-Authenticate: Basic realm="" Content-Length: 1656 Content-Type: text/html Content-Type: text/html; charset=Windows-1252 Client-Date: Tue, 28 Oct 2008 12:37:46 GMT Client-Peer: Client-Response-Num: 1 Client-SSL-Cert-Issuer: /O=VeriSign Trust Network/OU=VeriSign, Inc./OU +=VeriSign International Server CA - Class 3/ I Ref. LIABILITY LTD.(c)97 VeriSign (NOTE---Sensitive information removed by perlchild) Client-SSL-Cipher: RC4-MD5 Client-SSL-Warning: Peer certificate not verified Client-Warning: Unsupported authentication scheme 'negotiate' Title: You are not authorized to view this page X-Powered-By: ASP.NET <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" " +R/html4/strict.dtd"><HTML><HEAD><TITLE>You are not authorized to view + this page</TITLE><META HTTP-EQUIV="Content-Type" Content="text/html; charse +t=Windows-1252"><STYLE type="text/css"> BODY { font: 8pt/12pt verdan +a } H1 { font: 13pt/15pt verdana } H2 { font: 8pt/12pt verdana } A:link { color: re +d } A:visited { color: maroon }</STYLE></HEAD><BODY><TABLE width=500 + border=0 cellspacing=10><TR><TD><h1>You are not authorized to view this page</h +1>You do not have permission to view this directory or page using the + credentials that you supplied because your Web browser is sending a WWW-Authenticate he +ader field that the Web server is not configured to accept.<hr><p>Ple +ase try the following:</p><ul><li>Contact the Web site administrator if you believ +e you should be able to view this directory or page.</li><li>Click th +e <a href="javascript:location.reload()">Refresh</a> button to try again wi +th different credentials.</li></ul><h2>HTTP Error 401.2 - Unauthorize +d: Access is denied due to server configuration.<br>Internet Information Services ( +IIS)</h2><hr><p>Technical Information (for support personnel)</p><ul> +<li>Go to <a href="">Microsoft Product S +upport Services</a> and perform a title search for the words <b>HTTP< +/b> and <b>401</b>.</li><li>Open <b>IIS Help</b>, which is accessible in IIS M +anager (inetmgr), and search for topics titled <b>About Security</b>, + <b>Authentication</b>, and <b>About Custom Error Messages</b>.</li></u +l></TD></TR></TABLE></BODY></HTML> SOAP::Deserializer::deserialize: () SOAP::Parser::decode: () 401 Unauthorized at line 25 SOAP::Data::DESTROY: () SOAP::Data::DESTROY: () SOAP::Data::DESTROY: () SOAP::Lite::DESTROY: () SOAP::Deserializer::DESTROY: () SOAP::Transport::DESTROY: () SOAP::Transport::HTTP::Client::DESTROY: () SOAP::Serializer::DESTROY: () SOAP::Data::DESTROY: () SOAP::Parser::DESTROY: () SOAP::Transport::DESTROY: () SOAP::Serializer::DESTROY: () SOAP::Deserializer::DESTROY: () SOAP::Lite::DESTROY: ()

From the output it looks like the credentials that I pass to the soap->proxy call are not being used properly in the LWP calls.

I really don't understand how SOAP::Lite and LWP work together so I don't know how to implement this the correct way. I have searched all the docs on all the packages used in this script as well as all the info I could find on the internet and this site, which is not very much, and can't find a reliable implementation using SOAP::Lite, and the NTLM package. Maybe a perlmonk expert can help me with this problem.

Replies are listed 'Best First'.
Re: NTLM Authentication with SOAP::Lite not working
by Anonymous Monk on Oct 28, 2008 at 13:38 UTC

      Thank you so very much Anonymous Monk. I added that

      sub SOAP::Transport::HTTP::Client::get_basic_credentials { return ('user' => 'password') };

      line and now it works perfectly!! I gave you a positive vote. Thanks again!!!

        I'm not sure how overriding the get_basic_credentials method solves your problem, but it seems like a bad idea. You should read the LWP::Authen::Ntlm documentation, it includes a clear example of usage.