beets
asked on
Perl access with Integrated Windows Authentication
I have a Perl Script which works when Basic Authentication is used but gives Http Error 401 after the IIS Authentication Method is changed to "Integrated Windows Authentication" on Windows 2000.
The script is:
# non-buffered output to server
$|=1;
use LWP::UserAgent;
use URI::URL;
local $ua = LWP::UserAgent->new;
$ua->timeout(20); # set our BASIS WEBserver timeout to 20 seconds
$myoutput = "";
$item = 1;
do {
local $req = HTTP::Request->new(GET => "http://nztva$dbmv"."DDW?W=$url\&m=$item\&R =Y\&U=1\n\ n");
$req->authorization_basic( "b","c"); # uid and password for authorized WWW sources
$res =$ua->request($req);
$myoutput = $myoutput . $res->content;
$item++;
} while ($item <= $tmem); # end do
$myoutput =~ s/\r/\r~/g;
print "Content-type: text/html\n";
print "Content-Length: " . length($myoutput) . "\n\n";
$myoutput =~ s/\r~/\r/g;
print $myoutput;
}
exit;
This script concatenantes a series of web pages into 1 page for display. I get a series of 401 authentication errors instead of the data:
HTTP Error 401
401.2 Unauthorized: Logon Failed due to server configuration
How do I need to change the line:
$req->authorization_basic( "b","c"); # uid and password for authorized WWW sources
To allow access when using Integrated Windows Authentication on Windows 2000 and Windows NT Challenge/Response on Windows NT?
I'm sure it's easy to do but I don't know how!
Thanks for your Help.
The script is:
# non-buffered output to server
$|=1;
use LWP::UserAgent;
use URI::URL;
local $ua = LWP::UserAgent->new;
$ua->timeout(20); # set our BASIS WEBserver timeout to 20 seconds
$myoutput = "";
$item = 1;
do {
local $req = HTTP::Request->new(GET => "http://nztva$dbmv"."DDW?W=$url\&m=$item\&R
$req->authorization_basic(
$res =$ua->request($req);
$myoutput = $myoutput . $res->content;
$item++;
} while ($item <= $tmem); # end do
$myoutput =~ s/\r/\r~/g;
print "Content-type: text/html\n";
print "Content-Length: " . length($myoutput) . "\n\n";
$myoutput =~ s/\r~/\r/g;
print $myoutput;
}
exit;
This script concatenantes a series of web pages into 1 page for display. I get a series of 401 authentication errors instead of the data:
HTTP Error 401
401.2 Unauthorized: Logon Failed due to server configuration
How do I need to change the line:
$req->authorization_basic(
To allow access when using Integrated Windows Authentication on Windows 2000 and Windows NT Challenge/Response on Windows NT?
I'm sure it's easy to do but I don't know how!
Thanks for your Help.
ASKER
I tried this before and it didn't help. Could the fact that the Windows 2000 users login via a Domain cause it not to work in Perl?
ASKER
I used the administrator username and password and they didn't work either.
I've just tried to set up a small test based on your example, it doesn't work for me either... without domains. There may be an issue with LWP and Integrated Windows Authentication.
Anyone else get this?
Anyone else get this?
You might see whether the module
LWP::Authen::Ntlm
http://search.cpan.org/~gaas/libwww-perl-5.79/lib/LWP/Authen/Ntlm.pm
can be used for your purposes.
LWP::Authen::Ntlm
http://search.cpan.org/~gaas/libwww-perl-5.79/lib/LWP/Authen/Ntlm.pm
can be used for your purposes.
ASKER
hello jmcg,
Am trying your suggestion. (Am running Perl v5.6.1)
Am having trouble getting it to work displaying a series of appended html documents as per my posting.
Could you edit and paste the perl in my original posting as a reply getting an html page more than once? A $ua->credentials line appears to be needed before the GET line and I can't get this working when getting more than 1 document using $req-> credentials instead.
I'm testing on a system with no Domain, I presume this still works by leaving off "MyDomain\\" from the User Name.
Many Thanks.
Am trying your suggestion. (Am running Perl v5.6.1)
Am having trouble getting it to work displaying a series of appended html documents as per my posting.
Could you edit and paste the perl in my original posting as a reply getting an html page more than once? A $ua->credentials line appears to be needed before the GET line and I can't get this working when getting more than 1 document using $req-> credentials instead.
I'm testing on a system with no Domain, I presume this still works by leaving off "MyDomain\\" from the User Name.
Many Thanks.
Sorry, I have no experience with the module. I can't set up a test environment to verify that what I'm telling you is likely to be useful....
============
The $ua->credentials line should be inserted after you create the $ua object, but outside the loop. It needs to place the host address in a particular form, since that's how the rest of the module later does lookup. Here's my best guess at how the code should look:
.
.
.
local $ua = LWP::UserAgent->new;
$ua->timeout(20); # set our BASIS WEBserver timeout to 20 seconds
# set up credential for implicit use by Authen::NTLM
$ua->credentials( "nztva$dbmw:80", "", "MyDomain\\MyUsername", "MyPassword");
$myoutput = "";
$item = 1;
do {
local $req = HTTP::Request->new(GET => "http://nztva$dbmv"."DDW?W=$url\&m=$item\&R =Y\&U=1\n\ n");
# $req->authorization_basic( "b","c"); # uid and password for authorized WWW sources
$res =$ua->request($req);
$myoutput = $myoutput . $res->content;
.
.
.
============
I'm afraid I have no idea of how you have a Windows authentication protocol working without some sort of Workgroup or Domain name as part of the identification.
You must also have downloaded and installed the correct Athen::NTLM module where Perl can find it, as described in the LWP::Authen::Ntlm doc I pointed you to earlier.
============
The $ua->credentials line should be inserted after you create the $ua object, but outside the loop. It needs to place the host address in a particular form, since that's how the rest of the module later does lookup. Here's my best guess at how the code should look:
.
.
.
local $ua = LWP::UserAgent->new;
$ua->timeout(20); # set our BASIS WEBserver timeout to 20 seconds
# set up credential for implicit use by Authen::NTLM
$ua->credentials( "nztva$dbmw:80", "", "MyDomain\\MyUsername", "MyPassword");
$myoutput = "";
$item = 1;
do {
local $req = HTTP::Request->new(GET => "http://nztva$dbmv"."DDW?W=$url\&m=$item\&R
# $req->authorization_basic(
$res =$ua->request($req);
$myoutput = $myoutput . $res->content;
.
.
.
============
I'm afraid I have no idea of how you have a Windows authentication protocol working without some sort of Workgroup or Domain name as part of the identification.
You must also have downloaded and installed the correct Athen::NTLM module where Perl can find it, as described in the LWP::Authen::Ntlm doc I pointed you to earlier.
ASKER
I am using a Workgroup (called WORKGROUP) instead of a Domain. I tried "WORKGROUP\\Administrator" as the username - which didn't work. Is this the correct format for the credentials line username with a workgroup?
I downloaded the Ntlm.pm file via the Source hyperlink at the top of the page. I could not find where the documentation said to place the file so I placed it in: C:\Perl\site\lib\LWP and in c:\Perl\site\lib\LWP\Authe n directories. (is this correct? The Readme file didn't give the directory).
I inserted the $ua->credentials line after creating the $ua object outside the loop as per your last suggestion and commented out the existing authorization_basic line.
If I try to get 1 document, I get Http 401.2 error.
If I try to retrieve 2 or more (i.e. the do loop executes more than once) I get:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
Can't locate object method "authenticate" via package "LWP::Authen::Ntlm" (perhaps you forgot to load "LWP::Authen::Ntlm"?) at C:/Perl/site/lib/LWP/UserA gent.pm line 341.
I'm annoyed that I can't see where to place the Ntlm file. The sample code on the cpan page returns "It didn't work! 401" Access Denied.
If I can get the directory name correct and the Username format I will make some progress. Where is ntlm.pm on your PC?
I downloaded the Ntlm.pm file via the Source hyperlink at the top of the page. I could not find where the documentation said to place the file so I placed it in: C:\Perl\site\lib\LWP and in c:\Perl\site\lib\LWP\Authe
I inserted the $ua->credentials line after creating the $ua object outside the loop as per your last suggestion and commented out the existing authorization_basic line.
If I try to get 1 document, I get Http 401.2 error.
If I try to retrieve 2 or more (i.e. the do loop executes more than once) I get:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
Can't locate object method "authenticate" via package "LWP::Authen::Ntlm" (perhaps you forgot to load "LWP::Authen::Ntlm"?) at C:/Perl/site/lib/LWP/UserA
I'm annoyed that I can't see where to place the Ntlm file. The sample code on the cpan page returns "It didn't work! 401" Access Denied.
If I can get the directory name correct and the Username format I will make some progress. Where is ntlm.pm on your PC?
Oh, this error message is very encouraging. It indicates that the LWP package saw an Authenticate header using NTLM and tried to reach for the LWP::Authen::Ntlm module without being told explicitly by you that that's what you wanted to use. I think it means we're on the right track.
If you did not already have a module at
C:\Perl\site\lib\LWP\Authe n\Ntlm.pm
it may be necessary to update your entire LWP install. That module should have been there without any need to download it specifically. And I don't understand why the message says it can't find it if you put it there (unless you miscapitalized the name or something like that).
You don't mention downloading and installing the Authen::NTLM module:
http://search.cpan.org/~markbush/NTLM-1.02/
These would presumably go in
C:\Perl\site\lib\Authen\NT LM.pm
C:\Perl\site\lib\Authen\NT LM\DES.pm
C:\Perl\site\lib\Authen\NT LM\MD4.pm
and you need to check on the MIME::Base64 exporting of encode_base64( ) and decode_base64( ) as mentioned in the doc.
=======
I'll repeat: I don't have a system where I can try any of this out. I suspect WORKGROUP\Username works, but I don't have enough experience with managed Windows environments to do more than guess.
If you did not already have a module at
C:\Perl\site\lib\LWP\Authe
it may be necessary to update your entire LWP install. That module should have been there without any need to download it specifically. And I don't understand why the message says it can't find it if you put it there (unless you miscapitalized the name or something like that).
You don't mention downloading and installing the Authen::NTLM module:
http://search.cpan.org/~markbush/NTLM-1.02/
These would presumably go in
C:\Perl\site\lib\Authen\NT
C:\Perl\site\lib\Authen\NT
C:\Perl\site\lib\Authen\NT
and you need to check on the MIME::Base64 exporting of encode_base64( ) and decode_base64( ) as mentioned in the doc.
=======
I'll repeat: I don't have a system where I can try any of this out. I suspect WORKGROUP\Username works, but I don't have enough experience with managed Windows environments to do more than guess.
It looks like you'll need to add this line at about the same place where you have the $ua->credentials call, if you haven't already.
my $ua = new LWP::UserAgent(keep_alive= >1);
And be sure read the LWP::Authen::Ntlm doc for more wrinkles.
my $ua = new LWP::UserAgent(keep_alive=
And be sure read the LWP::Authen::Ntlm doc for more wrinkles.
ASKER
I already had the UserAgent(keep_alive=>1) line. I hadn't downloaded the Authen::NTLM module. (I have not downloaded anything other than "Ntlm.pm" Script hyperlink and added it to Perl. The LWP package I have is what comes with perl 5.6.1 build 626.
I downloaded the NTLM module and unzipped and compiled it to get the following:
C:\Perl\NTLM-1.02>perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Authen::NTLM::DES
Writing Makefile for Authen::NTLM::MD4
Writing Makefile for Authen::NTLM
C:\Perl\NTLM-1.02>make
MAKE Version 5.2 Copyright (c) 1987, 1998 Inprise Corp.
Fatal makefile 674: No terminator specified for in-line file operator
C:\Perl\NTLM-1.02>
I do not understand the "No terminator ..." error above.
Do I need to upgrade Perl completely for NTLM Authentication to work perhaps?
I downloaded the NTLM module and unzipped and compiled it to get the following:
C:\Perl\NTLM-1.02>perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Authen::NTLM::DES
Writing Makefile for Authen::NTLM::MD4
Writing Makefile for Authen::NTLM
C:\Perl\NTLM-1.02>make
MAKE Version 5.2 Copyright (c) 1987, 1998 Inprise Corp.
Fatal makefile 674: No terminator specified for in-line file operator
C:\Perl\NTLM-1.02>
I do not understand the "No terminator ..." error above.
Do I need to upgrade Perl completely for NTLM Authentication to work perhaps?
ASKER
I have always downloaded perl from www.activestate.com with no requirement to compile or make files. I wonder if their latest version will have the NTLM module and others loaded into the correct directories. The CPAN site download files need compiling or is NTLM an "add on" module that doesn't come with the latest version of Perl?
The "No terminator" error is most likely caused by using an incompatible version of the 'make' utility.
Yes, packages from ActiveState need no compilation on your machine. The Authen::NTLM module appears to be available for PPM. No Perl distribution includes all of the CPAN modules. Adding on external modules, whether as PPM packages for ActivePerl or from CPAN for UNIX and Linux systems, is usually quite painless.
Yes, packages from ActiveState need no compilation on your machine. The Authen::NTLM module appears to be available for PPM. No Perl distribution includes all of the CPAN modules. Adding on external modules, whether as PPM packages for ActivePerl or from CPAN for UNIX and Linux systems, is usually quite painless.
ASKER
Okay, some progress. I updated Perl 5.8.3 build 809 from Activestate. It already has a copy of Ntlm.pm in C:\Perl\site\lib\LWP\Authe n.
I presume I still need to add the Authen::NTLM module as per your instructions for the Windows Authentication to work. This time perl Makefile.PL worked however the next command: make started okay but stopped with the error:
mkdir Authen::NTLM::.: Invalid argument at C:/Perl/lib/ExtUtils/Insta ll.pm line 455
this happens after a screenful of lines of cp messages.
Install.pm line 455 has: mkpath(dirname($to),0,0755 );
Is adding the Authen::NTLM module is still necessary with this new version of perl? If so, what is the Invalid Argument about? (I currently get concatenated pages of 401 Authentication failed messages if I try to display 1 or more pages or do loop iterations).
I presume I still need to add the Authen::NTLM module as per your instructions for the Windows Authentication to work. This time perl Makefile.PL worked however the next command: make started okay but stopped with the error:
mkdir Authen::NTLM::.: Invalid argument at C:/Perl/lib/ExtUtils/Insta
this happens after a screenful of lines of cp messages.
Install.pm line 455 has: mkpath(dirname($to),0,0755
Is adding the Authen::NTLM module is still necessary with this new version of perl? If so, what is the Invalid Argument about? (I currently get concatenated pages of 401 Authentication failed messages if I try to display 1 or more pages or do loop iterations).
Can you check the authorship of the Authen::NTLM package you downloaded?
I would have thought the thing to do was to use PPM to get the package. That should not have required any Makefile.
I would have thought the thing to do was to use PPM to get the package. That should not have required any Makefile.
ASKER
PPM worked and NTLM is finally installed properly! (Will use PPM from now on).
Now I only have the message: HTTP 401.2 - Unauthorized: Logon failed due to server configuration Internet Information Services
This may be due to using a Workgroup (called WORKGROUP) rather than a Domain. I need to get the syntax of the Username correct for a Workgroup connection - perhaps someone else knows this. I have looked on the Internet and all examples use Domains.
The CPAN sample code modified below returns "It didn't work!-> 401
use LWP::UserAgent;
use HTTP::Request::Common;
use LWP::Debug qw(+);
my $url = "http://acer600/bold.html";
$uid = "WORKGROUP\\Administrator" ;
$upw = "mypassword";
# Set up the ntlm client and then the base64 encoded ntlm handshake message
my $ua = new LWP::UserAgent(keep_alive= >1);
$ua->credentials('http://acer600:80', '', $uid, $upw);
$request = GET $url;
print "--Performing request now...-----------\n";
$response = $ua->request($request);
print "--Done with request------------------- \n";
if ($response->is_success) {print "It worked!->" . $response->code . "\n"}
else {print "It didn't work!->" . $response->code . "\n"}
This produces the following:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
LWP::UserAgent::new: ()
LWP::UserAgent::request: ()
LWP::UserAgent::send_reque st: GET http://acer600/bold.html
LWP::UserAgent::_need_prox y: Not proxied
LWP::Protocol::http::request: ()
LWP::Protocol::collect: read 811 bytes
LWP::Protocol::collect: read 3620 bytes
LWP::UserAgent::request: Simple response: Unauthorized
LWP::Authen::Ntlm::authent icate: authenticate() has been called
LWP::Authen::Ntlm::authent icate: No username and password available from get_basic_credentials(). Returning unmodified response object
--Performing request now...-----------
--Done with request-------------------
It didn't work!->401
The URL http://acer600/bold.html works okay if entered direct in IE.
My modified perl script also produces a HTTP 401.2 error message for each concatenated page.
Is this supported using Workgroups? Have tried WORKGROUP\Administrator with 1 slash and others with mixed case - all don't work.
Now I only have the message: HTTP 401.2 - Unauthorized: Logon failed due to server configuration Internet Information Services
This may be due to using a Workgroup (called WORKGROUP) rather than a Domain. I need to get the syntax of the Username correct for a Workgroup connection - perhaps someone else knows this. I have looked on the Internet and all examples use Domains.
The CPAN sample code modified below returns "It didn't work!-> 401
use LWP::UserAgent;
use HTTP::Request::Common;
use LWP::Debug qw(+);
my $url = "http://acer600/bold.html";
$uid = "WORKGROUP\\Administrator"
$upw = "mypassword";
# Set up the ntlm client and then the base64 encoded ntlm handshake message
my $ua = new LWP::UserAgent(keep_alive=
$ua->credentials('http://acer600:80', '', $uid, $upw);
$request = GET $url;
print "--Performing request now...-----------\n";
$response = $ua->request($request);
print "--Done with request-------------------
if ($response->is_success) {print "It worked!->" . $response->code . "\n"}
else {print "It didn't work!->" . $response->code . "\n"}
This produces the following:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
LWP::UserAgent::new: ()
LWP::UserAgent::request: ()
LWP::UserAgent::send_reque
LWP::UserAgent::_need_prox
LWP::Protocol::http::request: ()
LWP::Protocol::collect: read 811 bytes
LWP::Protocol::collect: read 3620 bytes
LWP::UserAgent::request: Simple response: Unauthorized
LWP::Authen::Ntlm::authent
LWP::Authen::Ntlm::authent
--Performing request now...-----------
--Done with request-------------------
It didn't work!->401
The URL http://acer600/bold.html works okay if entered direct in IE.
My modified perl script also produces a HTTP 401.2 error message for each concatenated page.
Is this supported using Workgroups? Have tried WORKGROUP\Administrator with 1 slash and others with mixed case - all don't work.
It seems odd that there should be a call to "get_basic_credentials" in there. It seems to be falling back to that after failing to find the credentials you supplied. Ah, you have "http://" leading the host name part of the lookup string. Get rid of it. It should look more like:
$ua->credentials('acer600: 80', '', $uid, $upw);
Do you have any ability to snoop on the connection made with IE? That might let you figure out what format will work for the credentials.
$ua->credentials('acer600:
Do you have any ability to snoop on the connection made with IE? That might let you figure out what format will work for the credentials.
ASKER
Thank you, removing the http:// string worked (well spotted!) - at least in my perl script that I originally sent with my question.
The CPAM sample code failed with:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
LWP::UserAgent::new: ()
LWP::UserAgent::request: ()
LWP::UserAgent::send_reque st: GET http://acer600/bold.html
LWP::UserAgent::_need_prox y: Not proxied
LWP::Protocol::http::request: ()
LWP::Protocol::collect: read 811 bytes
LWP::Protocol::collect: read 3620 bytes
LWP::UserAgent::request: Simple response: Unauthorized
LWP::Authen::Ntlm::authent icate: authenticate() has been called
LWP::Authen::Ntlm::authent icate: In first phase of NTLM authentication
LWP::Authen::Ntlm::authent icate: Returning response object with auth header:
Authorization NTLM TlRMTVNTUAABAAAAB7IAAA0ADQ AgAAAACQAJ AC0AAABBZG 1pbmlzdHJh dG9yV29ya2 dyb3Vw
LWP::UserAgent::request: ()
LWP::UserAgent::send_reque st: GET http://acer600/bold.html
LWP::UserAgent::_need_prox y: Not proxied
LWP::Protocol::http::request: ()
LWP::Protocol::
But I don't care about that code!
Okay I'd like to award you the points but with the answer spread over all your comments perhaps you could send a final comment with a summary of what was required like below and I'll award them. This may be easier for others to follow. Summarized from above comments:
- Windows Authentication requires installation of the NTLM package.
- Use the perl utility PPM to search for NTLM and then install it (or download it if it is not present):
- A $ua->credentials line should be inserted after you create the $ua object, but before the loop (The Domain name may also be a Workgroup name):
my $ua = new LWP::UserAgent(keep_alive= >1);
$ua->credentials('acer600: 80','','Do main\\user name', 'password');
- Comment out the authorization_basic line
-This will allow Windows Authentication on each concatenated page using NTLM
-------------
Thank you, I appreciate all your help and patience.
The CPAM sample code failed with:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
LWP::UserAgent::new: ()
LWP::UserAgent::request: ()
LWP::UserAgent::send_reque
LWP::UserAgent::_need_prox
LWP::Protocol::http::request: ()
LWP::Protocol::collect: read 811 bytes
LWP::Protocol::collect: read 3620 bytes
LWP::UserAgent::request: Simple response: Unauthorized
LWP::Authen::Ntlm::authent
LWP::Authen::Ntlm::authent
LWP::Authen::Ntlm::authent
Authorization NTLM TlRMTVNTUAABAAAAB7IAAA0ADQ
LWP::UserAgent::request: ()
LWP::UserAgent::send_reque
LWP::UserAgent::_need_prox
LWP::Protocol::http::request: ()
LWP::Protocol::
But I don't care about that code!
Okay I'd like to award you the points but with the answer spread over all your comments perhaps you could send a final comment with a summary of what was required like below and I'll award them. This may be easier for others to follow. Summarized from above comments:
- Windows Authentication requires installation of the NTLM package.
- Use the perl utility PPM to search for NTLM and then install it (or download it if it is not present):
- A $ua->credentials line should be inserted after you create the $ua object, but before the loop (The Domain name may also be a Workgroup name):
my $ua = new LWP::UserAgent(keep_alive=
$ua->credentials('acer600:
- Comment out the authorization_basic line
-This will allow Windows Authentication on each concatenated page using NTLM
-------------
Thank you, I appreciate all your help and patience.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Can't you just change
$req->authorization_basic(
to the user name and password of any user account on the server that has read/write access to the web pages? like yours?