Home > Tutorial > SharePoint and NTLMv2 with SOAP::Lite

SharePoint and NTLMv2 with SOAP::Lite

In this article I will be presenting a mini-tutorial on how to integrate with SharePoint including NTLMv2 authentication using the Perl SOAP::Lite framework. This article is not a repeat of all the other tutorials you see on the Internet related to this topic.

When I first tried to get this complicated mess to work I was annoyed at the lack of good documentation on this subject. After scouring the Internet for information and doing my own painstakingly line-by-line debugging of the SOAP transport I finally got it all to work and understand the various steps required (or at least I think I do). Note: I only have experience with my organization’s SharePoint 2010 server and I can’t guarantee that the following will work with other configurations.

I’ll start by showing a full example of how to connect to the SharePoint web service and then I’ll walk through the code with you to explain how and why things are working.

#!/usr/bin/perl
# @file ex_soap1.pl
use strict;
use warnings;
use Data::Dumper;
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Indent = 1;

use Authen::NTLM;
use SOAP::Lite;

# enable debugging ...
SOAP::Lite->import(+trace => 'all');

my $user = '\\username';    # must have leading slash (do not include domain)
my $pass = 'password';
my $host = 'my.sharepointsite.com:443';    # always include the port
my $endpoint = "https://$host/_vti_bin/Lists.asmx";

# enable NTLMv2 in Authen::NTLM
ntlmv2(1);

my $soap = SOAP::Lite
	->proxy($endpoint, keep_alive => 1, credentials => [$host, '', $user, $pass])
	->default_ns('http://schemas.microsoft.com/sharepoint/soap/')
	->on_action(sub { $_[0] . $_[1] })  # change default SOAPAction header
	->readable(1)	# optional; useful for debugging XML traces
	;

# Fetch a list of all list collections available...
my $som = $soap->GetListCollection();
die $som->faultstring() if defined $som->fault();
my @result = $som->dataof('//GetListCollectionResult/Lists/List');
foreach my $data (@result) {
	my $item = $data->attr;
	print Dumper($item);
}

There you have it. Except for the debugging and Dumper code that example is about as succinct and easy as you can get. I’d be interested in hearing if this example didn’t actually work for you.

For anyone that has read other tutorials on this subject you may notice that I don’t use LWP::UserAgent. The fact is, you don’t need it. By default SOAP::Transport::HTTP::Client extends LWP::UserAgent which means you can simply pass extra LWP::UserAgent parameters to the proxy() method (I won’t go into detail on how you can change this default behavior).

SharePoint Specifics

There are a couple of nuances you must follow in order for your SOAP calls to work properly with SharePoint.

  1. The username must have a leading slash. And in my tests I had to omit the DOMAIN even though my organization is part of an AD DOMAIN. This is due to what I see as a bug in the LWP::Authen::Ntlm authenticate() method where it blindly assumes the username string is in the format of “domain\username” and splits it on the slash which causes it to use an empty string for the username instead of the username you set.
  2. The host name must include the port, even if its a standard 80 or 443. This is required for NTLMv2 to work properly. I’m not 100% sure but I believe its used as part of the hashing algorithm. Correct me if I’m wrong.
  3. The namespace must be set correctly, to be specific: “http://schemas.microsoft.com/sharepoint/soap/”. Also note that a lot of tutorials on this topic say to use the uri() method to set the service URI, that advice is actually outdated/deprecated and you should be using the default_ns() method instead.
  4. A proper “SOAPAction” header must be set using the on_action() method. SOAP::Lite defaults to sending the SOAPAction as “uri#method” and SharePoint requires it to be “uri/method”.
  5. NTLM authentification works only with HTTP persistent connections (Keep Alive). So (keep_alive =>1) must be enabled in the proxy() setup.
  6. Pass the NTLM login credentials to the proxy() method using an array reference of [host, realm, user, pass]. “realm” must be an empty string and the host must include the full host name and port.

See the highlighted lines below for the items outlined above.

my $user = '\\username';    # must have leading slash (do not include domain)
my $pass = 'password';
my $host = 'my.sharepointsite.com:443';    # always include the port
my $endpoint = "https://$host/_vti_bin/Lists.asmx";

# enable NTLMv2 in Authen::NTLM; Not everyone will need this.
ntlmv2(1);

my $soap = SOAP::Lite
	->proxy($endpoint, keep_alive => 1, credentials => [$host, '', $user, $pass])
	->default_ns('http://schemas.microsoft.com/sharepoint/soap/')
	->on_action(sub { $_[0] . $_[1] })  # change default SOAPAction header
	->readable(1)	# optional; useful for debugging XML traces
	;

Last but not least you’ll want to do something useful now that you’re connected and in this example I show a quick and dirty way to pull a list of all collections on the site.

my $som = $soap->GetListCollection();
die $som->faultstring() if defined $som->fault();
my @result = $som->dataof('//GetListCollectionResult/Lists/List');
foreach my $data (@result) {
	my $item = $data->attr;
	print Dumper($item);
}

When you make a SOAP call you get a SOAP::SOM object back which automatically de-serializes the XML response and allows you to traverse the response with XPath syntax. This makes it extremely easy to find the results you want and iterate over them using only a few lines of code.

That’s about it for this tutorial. In a follow-up tutorial I will show how to fetch the list of items from a list collection.

About these ads
Categories: Tutorial Tags: ,
  1. Kanwar
    August 20, 2012 at 11:39 pm | #1

    thank you. much appreciated

  2. Elvis
    February 7, 2013 at 11:52 pm | #2

    This is really cool, I found this code is the exact one which works with NTLMv2 Authentication, Can you please show a code to know how I can call each method in the WSDL file with exact parameters. GETLISTITEMS, COPY , ADD LIST, DELETE LIST , ETC

  1. May 9, 2012 at 8:56 am | #1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: