1 package LWP::Authen::Ntlm;
8 use Authen::NTLM "1.02";
9 use MIME::Base64 "2.12";
12 my($class, $ua, $proxy, $auth_param, $response,
13 $request, $arg, $size) = @_;
15 my($user, $pass) = $ua->get_basic_credentials($auth_param->{realm},
16 $request->uri, $proxy);
18 unless(defined $user and defined $pass) {
22 if (!$ua->conn_cache()) {
23 warn "The keep_alive option must be enabled for NTLM authentication to work. NTLM authentication aborted.\n";
27 my($domain, $username) = split(/\\/, $user);
33 my $auth_header = $proxy ? "Proxy-Authorization" : "Authorization";
35 # my ($challenge) = $response->header('WWW-Authenticate');
37 foreach ($response->header('WWW-Authenticate')) {
38 last if /^NTLM/ && ($challenge=$_);
41 if ($challenge eq 'NTLM') {
42 # First phase, send handshake
43 my $auth_value = "NTLM " . ntlm();
46 # Need to check this isn't a repeated fail!
50 my $auth = $r->request->header($auth_header);
51 ++$retry_count if ($auth && $auth eq $auth_value);
52 if ($retry_count > 2) {
53 # here we know this failed before
54 $response->header("Client-Warning" =>
55 "Credentials for '$user' failed before");
61 my $referral = $request->clone;
62 $referral->header($auth_header => $auth_value);
63 return $ua->request($referral, $arg, $size, $response);
67 # Second phase, use the response challenge (unless non-401 code
68 # was returned, in which case, we just send back the response
71 if ($response->code ne '401') {
76 foreach ($response->header('WWW-Authenticate')) {
77 last if /^NTLM/ && ($challenge=$_);
79 $challenge =~ s/^NTLM //;
81 $auth_value = "NTLM " . ntlm($challenge);
85 my $referral = $request->clone;
86 $referral->header($auth_header => $auth_value);
87 my $response2 = $ua->request($referral, $arg, $size, $response);
97 LWP::Authen::Ntlm - Library for enabling NTLM authentication (Microsoft) in LWP
102 use HTTP::Request::Common;
103 my $url = 'http://www.company.com/protected_page.html';
105 # Set up the ntlm client and then the base64 encoded ntlm handshake message
106 my $ua = new LWP::UserAgent(keep_alive=>1);
107 $ua->credentials('www.company.com:80', '', "MyDomain\\MyUserCode", 'MyPassword');
110 print "--Performing request now...-----------\n";
111 $response = $ua->request($request);
112 print "--Done with request-------------------\n";
114 if ($response->is_success) {print "It worked!->" . $response->code . "\n"}
115 else {print "It didn't work!->" . $response->code . "\n"}
119 C<LWP::Authen::Ntlm> allows LWP to authenticate against servers that are using the
120 NTLM authentication scheme popularized by Microsoft. This type of authentication is
121 common on intranets of Microsoft-centric organizations.
123 The module takes advantage of the Authen::NTLM module by Mark Bush. Since there
124 is also another Authen::NTLM module available from CPAN by Yee Man Chan with an
125 entirely different interface, it is necessary to ensure that you have the correct
128 In addition, there have been problems with incompatibilities between different
129 versions of Mime::Base64, which Bush's Authen::NTLM makes use of. Therefore, it is
130 necessary to ensure that your Mime::Base64 module supports exporting of the
131 encode_base64 and decode_base64 functions.
135 The module is used indirectly through LWP, rather than including it directly in your
136 code. The LWP system will invoke the NTLM authentication when it encounters the
137 authentication scheme while attempting to retrieve a URL from a server. In order
138 for the NTLM authentication to work, you must have a few things set up in your
139 code prior to attempting to retrieve the URL:
145 Enable persistent HTTP connections
147 To do this, pass the "keep_alive=>1" option to the LWP::UserAgent when creating it, like this:
149 my $ua = new LWP::UserAgent(keep_alive=>1);
153 Set the credentials on the UserAgent object
155 The credentials must be set like this:
157 $ua->credentials('www.company.com:80', '', "MyDomain\\MyUserCode", 'MyPassword');
159 Note that you cannot use the HTTP::Request object's authorization_basic() method to set
160 the credentials. Note, too, that the 'www.company.com:80' portion only sets credentials
161 on the specified port AND it is case-sensitive (this is due to the way LWP is coded, and
162 has nothing to do with LWP::Authen::Ntlm)
168 General queries regarding LWP should be made to the LWP Mailing List.
170 Questions specific to LWP::Authen::Ntlm can be forwarded to jtillman@bigfoot.com
174 Copyright (c) 2002 James Tillman. All rights reserved. This
175 program is free software; you can redistribute it and/or modify it
176 under the same terms as Perl itself.
180 L<LWP>, L<LWP::UserAgent>, L<lwpcook>.