libwww-perl / WWW-Mechanize

Handy web browsing in a Perl object
https://metacpan.org/pod/WWW::Mechanize
Other
68 stars 52 forks source link

Mech performing a Basic auth on a Digest auth only server when sending a PUT request. #316

Open rthawkcom opened 3 years ago

rthawkcom commented 3 years ago

I have a web device that only allows Digest authentication. If I use a GET request, it works just fine: GET http://10.1.2.61/restapi/relay/user_lines/ ==> 401 Unauthorized GET http://10.1.2.61/restapi/relay/user_lines/ ==> 200 OK $VAR1 = '["hi!"," Active! "]';

However, when I do a PUT request, it attempts a Basic auth and fails: PUT http://10.1.2.61/restapi/relay/beep_sequence/ ==> 401 Unauthorized PUT http://10.1.2.61/restapi/relay/beep_sequence/ ==> 401 Unauthorized Error PUTing http://10.1.2.61/restapi/relay/beep_sequence/: Unauthorized at /usr/local/share/perl/5.30.0/LWP/Authen/Basic.pm line 77.

oalders commented 3 years ago

If someone could put together a test case to demonstrate this, that would be helpful.

simbabque commented 3 years ago

I've created a test and it seems to work on current master with LWP::UserAgent on 6.49 and HTTP::Message on 6.29. The Plack script requires Plack::Middleware::Auth::Digest to be installed.

Plack server, run with plackup foo.pl:

use Plack::Builder;

my $app = sub { return [ 200, [ 'Content-Type' => 'text/plain' ], [ "Hello" ] ] };

builder {
    enable "Auth::Digest", realm => "Secured", secret => "bar",
    authenticator => sub {
        my ($username, $env) = @_;
        return 'password';
    };

    $app;
};

Test script, run with prove -lv t/99-put.t.

use strict;
use warnings;
use Test::More;
use WWW::Mechanize;
#use LWP::ConsoleLogger::Everywhere;

my $mech = WWW::Mechanize->new;
$mech->credentials('username', 'password');

$mech->put('http://localhost:5000/');
like $mech->res->request->header('Authorization'), qr/Digest/, 'Digest header sent';
is $mech->content, 'Hello', 'Content correct';

done_testing;

The test passes with both GET and PUT for me.

@rthawkcom can you please tell us which versions of WWW::Mechanize and LWP::UserAgent you are running? The easiest way of getting them is to run this and check in the error message. Thank you.

$ perl -MWWW::Mechanize\ 9
WWW::Mechanize version 9 required--this is only version 2.00.
BEGIN failed--compilation aborted.
rthawkcom commented 3 years ago

WWW::Mechanize version 9 required--this is only version 2.02.

My work around was to just use curl off the command line: return curl -s -u $pass -X $req -H 'X-CSRF: Perl;' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --digest $data '$url';

That works perfectly with no issues. I'm up and running, but not happy since this is not a pure Perl solution. Would prefer to use Mech if I can.

This is the appliance I built an API for that Mech is having problems with: https://www.amazon.com/Web-Power-Switch-Pro-Model/dp/B0765NCB2L/ If you are up for a small investment, they are really nice durable units! Great for home automation, not just rebooting servers.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Tuesday, December 22, 2020 4:48 AM, Julien Fiegehenn notifications@github.com wrote:

I've created a test and it seems to work on current master with LWP::UserAgent on 6.49 and HTTP::Message on 6.29. The Plack script requires Plack::Middleware::Auth::Digest to be installed.

Plack server, run with plackup foo.pl:

use

Plack::Builder;

my

$app

=

sub

{

return

[ 200, [

'

Content-Type

'

=>

'

text/plain

'

], [

"

Hello

"

] ] };

builder { enable

"

Auth::Digest

"

,

realm

=>

"

Secured

"

,

secret

=>

"

bar

"

,

authenticator

=>

sub

{

my

(

$username

,

$env

) =

@_

;

return

'

password

'

; };

$app

; };

Test script, run with prove -lv t/99-put.t.

use

strict;

use

warnings;

use

Test::More;

use

WWW::Mechanize;

#

use LWP::ConsoleLogger::Everywhere;

my

$mech

= WWW::Mechanize

->

new;

$mech

->

credentials(

'

username

'

,

'

password

'

);

$mech

->

put(

'

http://localhost:5000/

'

); like

$mech

->

res

->

request

->

header(

'

Authorization

'

),

qr

/

Digest

/

,

'

Digest header sent

'

; is

$mech

->

content,

'

Hello

'

,

'

Content correct

'

;

done_testing;

The test passes with both GET and PUT for me.

@rthawkcom can you please tell us which versions of WWW::Mechanize and LWP::UserAgent you are running? The easiest way of getting them is to run this and check in the error message. Thank you.

$ perl -MWWW::Mechanize\ 9 WWW::Mechanize version 9 required--this is only version 2.00. BEGIN failed--compilation aborted.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

simbabque commented 3 years ago

@rthawkcom thanks. Could you please also check your LWP::UserAgent version, and get LWP::ConsoleLogger and use LWP::ConsoleLogger::Everywhere to dump the headers of the requests your code sends with both GET and POST, and include these along with the server responses (should be two and two for each verb) as well. I am pretty sure this has to do with either something in your tool chain being a little out of date, or that this appliance is sending strange headers. We will look at them, and find a way of making this work.

As a last resort, you can always create your own authentication header and include it in the request manually.

Thank you.

rthawkcom commented 3 years ago

LWP::UserAgent version 9 required--this is only version 6.49.

Sure thing. Give me some time and I'll set up Wire Shark and dump the stream as well.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Tuesday, December 22, 2020 8:12 AM, Julien Fiegehenn notifications@github.com wrote:

@rthawkcom thanks. Could you please also check your LWP::UserAgent version, and get LWP::ConsoleLogger and use LWP::ConsoleLogger::Everywhere to dump the headers of the requests your code sends with both GET and POST, and include these along with the server responses (should be two and two for each verb) as well. I am pretty sure this has to do with either something in your tool chain being a little out of date, or that this appliance is sending strange headers. We will look at them, and find a way of making this work.

As a last resort, you can always create your own authentication header and include it in the request manually.

Thank you.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.