9

I tried to run this perl5 program:

 #!/usr/bin/env perl                                                             

use strict;                                                                     
use warnings;                                                                   
use LWP;                                                                        

my $ua = LWP::UserAgent->new('Mozilla');                                        
$ua->credentials("test.server.com:39272", "realm-name", 'user_name', 'some_pass');                       
my $res = $ua->get('http://test.server.com:39272/');                  

print $res->content;

On other hand I have HTTP::Daemon:

#!/usr/bin/env perl                                                                                       

use strict;                                                                     
use warnings;                                                                   

use HTTP::Daemon;                                                               

my $hd = HTTP::Daemon->new or die;                                              

print "Contact URL: ", $hd->url, "\n";                                          
while (my $hc = $hd->accept) {                                                  
  while (my $hr = $hc->get_request) {                                           
    if ($hr->method eq 'GET') {                                                 
      print $hr->as_string, "\n";                                               
    }                                                                           
  }                                                                             
  $hc->close;                                                                   
  undef($hc);                                                                   
}    

And it just prints:

Contact URL: http://test.server.com:39272/
GET / HTTP/1.1
Connection: TE, close
Host: test.server.com:39272
TE: deflate,gzip;q=0.3
User-Agent: libwww-perl/6.03

So I see that LWP::UserAgent don't send HTTP Basic auth, but I don't know why.

I seen some post on this web site, but they have this same basic code, and it doesn't work...

If I use HTTP::Request then it works:

my $req = GET 'http://test.server.com:39272/';                        
$req->authorization_basic('my_id', 'my_pass');                                  
my $res = $ua->request($req);

Outputs:

GET / HTTP/1.1
Connection: TE, close
Authorization: Basic bXlfaWQ6bXlfcGFzcw==
Host: test.server.com:39272
TE: deflate,gzip;q=0.3
User-Agent: libwww-perl/6.03

Did I done something wrong before?

XoR
  • 2,556
  • 4
  • 17
  • 15
  • 4
    Did you get a 401 response that requested basic auth? Did you get the realm right? Show the request-response chain, not just the request. – ikegami Nov 20 '11 at 19:19
  • Well I put code for request&response. And I did get 401 response. Don't understand about realm question, I don't see how that is important. – XoR Nov 20 '11 at 19:45
  • 1
    I know now, I need to return WWW-Authenticate: Basic realm="Secure Area", then LWP::UserAgent will work, right? – XoR Nov 20 '11 at 19:50
  • 2
    @XoR, yes, your server has to return a `401` status requesting basic auth (with the proper realm name) before LWP will send the auth credentials. – friedo Nov 20 '11 at 20:03
  • Aha, @friedo, now I know, thanks :) – XoR Nov 20 '11 at 20:33
  • If you don't understand realms, what did you put for the second argument of `credentials`? It has to be the realm returned in the 401 response. – ikegami Nov 21 '11 at 01:06

1 Answers1

20

LWP will only send the credentials for a realm if the server has told it that it's trying to access that realm. A particular user may only be able to access particular realms or have different passwords for different realms. LWP doesn't know which one to pick out of its credentials without the realm. Additionally, LWP isn't going to use the data you store in the credentials unless it's been challenged. You're not doing that.

If you supply the credentials directly by specifying the Authorization header, you do no realm checking. You can always send any header you like if you set it explicitly yourself, so it's not surprising that you see it.

You just need a better test server:

use strict;                                                                     
use warnings;                                                                   

use HTTP::Daemon;                                                               
use HTTP::Status;

my $server = HTTP::Daemon->new or die;                                              

print "Contact URL: ", $server->url, "\n";                                          
while (my $connection = $server->accept) {                                                  
    while (my $request = $connection->get_request) {                                           
        print $request->as_string;
        unless( $request->header( 'Authorization' ) ) {                                                 
            $connection->send_response( make_challenge() )                                               
            }
        else {
            $connection->send_response( make_response() )                                               
            }   
        }                                                                             
    $connection->close;                                                                   
    }  

sub make_challenge {
    my $response = HTTP::Response->new( 
        401 => 'Authorization Required',
        [ 'WWW-Authenticate' => 'Basic realm="Buster"' ],
         );
    }

sub make_response {
    my $response = HTTP::Response->new( 
        200 => 'Huzzah!',
        [ 'Content-type' => 'text/plain' ],
         );

    $response->message( 'Huzzah!' );
    }

When you run your client once, there should be two requests:

GET / HTTP/1.1
Connection: TE, close
Host: macpro.local:52902
TE: deflate,gzip;q=0.3
User-Agent: libwww-perl/6.02

GET / HTTP/1.1
Connection: TE, close
Authorization: Basic dXNlcl9uYW1lOnNvbWVfcGFzcw==
Host: macpro.local:52902
TE: deflate,gzip;q=0.3
User-Agent: libwww-perl/6.02
brian d foy
  • 129,424
  • 31
  • 207
  • 592