Mailing List Archive

Mod Perl and Basic Authentication
Hello,

I am trying to handle basic authentication using mod_perl 2.0.9 and Apache 2.4.18.

I am getting the first request to my resource. The user is requesting the URL without any username or password. My program should refuse the access to this resource and force the web browser to offer a dialogue box with realm, username and password. Here is what I tried:

$o_Req->auth_name('Login');
$o_Req->auth_type('Basic');
$o_Req->note_basic_auth_failure();
return Apache2::Const::HTTP_UNAUTHORIZED;

In fact the browser gets the 401 message, but does not open any dialog box. When debugging with curl I can see the "HTTP/1.1 401 Unauthorized” header, but I cannot see any trace of the authentication type “Basic” or name “Login”. So I try to send them manually:

$o_Req->note_basic_auth_failure();
$o_Req->headers_out->set('WWW-Authenticate' => "Basic");
$o_Req->headers_out->set('Realm' => "Login");
return Apache2::Const::HTTP_UNAUTHORIZED;

but I still cannot see the authentication type or name. I tried with a different return code “AUTH_REQUIRED”, but there was no difference in behaviour. Where is the difference between HTTP_UNAUTHORIZED and AUTH_REQUIRED?

I assume the browser does not open the dialog box for requesting the username and password, because he did not receive the realm name and authentication type. So how I can send these?

BTW, the same Programm runs fine using mod_perl 2.0.6 and Apache 2.2.x.

Thank you

Matthias Schmitt
Greetings from Luxembourg
Re: Mod Perl and Basic Authentication [ In reply to ]
On 02.03.2016 17:53, Matthias Schmitt wrote:
> Hello,
>
> I am trying to handle basic authentication using mod_perl 2.0.9 and Apache 2.4.18.
>
> I am getting the first request to my resource. The user is requesting the URL without any username or password. My program should refuse the access to this resource and force the web browser to offer a dialogue box with realm, username and password. Here is what I tried:
>
> $o_Req->auth_name('Login');
> $o_Req->auth_type('Basic');
> $o_Req->note_basic_auth_failure();
> return Apache2::Const::HTTP_UNAUTHORIZED;
>
> In fact the browser gets the 401 message, but does not open any dialog box. When debugging with curl I can see the "HTTP/1.1 401 Unauthorized” header, but I cannot see any trace of the authentication type “Basic” or name “Login”. So I try to send them manually:
>
> $o_Req->note_basic_auth_failure();
> $o_Req->headers_out->set('WWW-Authenticate' => "Basic");
> $o_Req->headers_out->set('Realm' => "Login");

I believe that the above is supposed to be a single HTTP header, not 2 :

WWW-Authenticate: Basic realm="Login"


> return Apache2::Const::HTTP_UNAUTHORIZED;
>
> but I still cannot see the authentication type or name. I tried with a different return code “AUTH_REQUIRED”, but there was no difference in behaviour. Where is the difference between HTTP_UNAUTHORIZED and AUTH_REQUIRED?
>
> I assume the browser does not open the dialog box for requesting the username and password, because he did not receive the realm name and authentication type. So how I can send these?
>
> BTW, the same Programm runs fine using mod_perl 2.0.6 and Apache 2.2.x.

There are some significant differences between the Apache 2.4 AAA logic and the 2.2 logic.
Have a look at CPAN. Search for Apache::AuthCookie, and look at the documents with the 2.4
suffix. There is an overview of the differences.

Another thing : above, you call your code "program". At what stage of the Apache request
cycle are you calling this code ? is this a Response handler, a PerlAuthenHandler, a
cgi-bin script ?
Re: Mod Perl and Basic Authentication [ In reply to ]
On Wed, 2 Mar 2016 17:53:39 +0100
Matthias Schmitt <freak002@mmp.lu> wrote:

> I am trying to handle basic authentication using mod_perl 2.0.9 and Apache 2.4.18.
>
>
> BTW, the same Programm runs fine using mod_perl 2.0.6 and Apache 2.2.x.

I don't use basic authentication myself so can't help you, but see 'Run-Time Configuration Changes' in :

https://httpd.apache.org/docs/2.4/upgrading.html






--
Bien à vous, Vincent Veyron

https://marica.fr/
Gestion des contentieux, des dossiers de sinistres assurance et des contrats pour le service juridique
Re: Mod Perl and Basic Authentication [ In reply to ]
Hello,

> On 02 Mar 2016, at 21:26, A. Warnier <aw@ice-sa.com> wrote:
>
>> $o_Req->note_basic_auth_failure();
>> $o_Req->headers_out->set('WWW-Authenticate' => "Basic");
>> $o_Req->headers_out->set('Realm' => "Login");
>
> I believe that the above is supposed to be a single HTTP header, not 2 :
>
> WWW-Authenticate: Basic realm="Login”

This makes no difference for my problem.

> Another thing : above, you call your code "program". At what stage of the Apache request cycle are you calling this code ? is this a Response handler, a PerlAuthenHandler, a cgi-bin script ?

This code snippet is part of a PerlResponseHandle. I cannot use it as part of a PerlAuthenHandler. When I would run it as a PerlAuthenHandler the user would always need to enter a password. This is my scenario:

I am programming a CMS with on demand publishing. If a user requests a URL it is unknown at the time of calling if the requested resource is public or if it is protected via a password. If my program decides that a password is required I would like to answer with a 401 response forcing the browser to ask a password. I can send the 401 response, but the browser never opens the dialog box for requesting a password.

Best regards

Matthias Schmitt
Re: Mod Perl and Basic Authentication [ In reply to ]
If the resource is not public and the user is not authenticated yet,
you can add the 'WWW-Authenticate' http header and return the
Apache2::Const::HTTP_UNAUTHORIZED status.
This will trigger the browser to show the login dialog.
You can also create a cookie and a session table in a database and check
with this session.
Example:

my $authheader = $r->headers_in->{Authorization};
$r->err_headers_out->set("WWW-Authenticate" => 'Basic realm="My Site"');

# user did not enter credentials yet
unless ($authheader){
return Apache2::Const::HTTP_UNAUTHORIZED
}

# get the user and password
my ($user, $passwd) = getBasicAuth(($authheader);

# check your user and password
unless (checkUserInDB($user, $passwd)){
return Apache2::Const::HTTP_UNAUTHORIZED
}

return Apache2::Const::OK

########################## sub getBasicAuth ##########################

sub getBasicAuth {

my $authheader = shift;
return unless $authheader;

my ($cram) = $authheader =~ /^Basic (.*)/;
return unless $cram;
$cram = MIME::Base64::decode_base64 ($cram);
return split (/:/, $cram, 2);

}


---

Thomas den Braber
Re: Mod Perl and Basic Authentication [ In reply to ]
Hello,

Yes! There is one very magic line in your code, which solved my problem. It is this line:

$r->err_headers_out->set("WWW-Authenticate" => 'Basic realm="My Site"’);

I always used:

$r->headers_out->set("WWW-Authenticate" => 'Basic realm="My Site"’);

When digging into the documentation one can read: "The difference between headers_out and err_headers_out, is that the latter are printed even on error, and persist across internal redirects (so the headers printed for ErrorDocument handlers will have them).”

When using Apache 2.2 with mod_perl 2.0.6 using “headers_out” was enough. When using Apache 2.4 with mod_perl 2.0.9 seems to be more correct. :-)

Thank you!!!

> On 08 Mar 2016, at 15:03, Thomas den Braber <thomas@delos.nl> wrote:
>
> If the resource is not public and the user is not authenticated yet,
> you can add the 'WWW-Authenticate' http header and return the Apache2::Const::HTTP_UNAUTHORIZED status.
> This will trigger the browser to show the login dialog.
> You can also create a cookie and a session table in a database and check with this session.
>
> Example:
>
> my $authheader = $r->headers_in->{Authorization};
> $r->err_headers_out->set("WWW-Authenticate" => 'Basic realm="My Site"');
>
> # user did not enter credentials yet
> unless ($authheader){
> return Apache2::Const::HTTP_UNAUTHORIZED
> }
>
> # get the user and password
> my ($user, $passwd) = getBasicAuth(($authheader);
>
> # check your user and password
> unless (checkUserInDB($user, $passwd)){
> return Apache2::Const::HTTP_UNAUTHORIZED
> }
>
> return Apache2::Const::OK
>
> ########################## sub getBasicAuth ##########################
>
> sub getBasicAuth {
>
> my $authheader = shift;
> return unless $authheader;
>
> my ($cram) = $authheader =~ /^Basic (.*)/;
> return unless $cram;
> $cram = MIME::Base64::decode_base64 ($cram);
> return split (/:/, $cram, 2);
>
> }

Best regards

Matthias Schmitt

magic moving pixel s.a.
23, Avenue Grande-Duchesse Charlotte
L-3441 Dudelange
Luxembourg
Phone: +352 54 75 75
http://www.mmp.lu