I have code which works with apache 2.2 but not apache 2.4, and I have boiled this down to a simple reproducing test case.

It works with: Ubuntu 12.04 (apache 2.2.22, mod_perl 2.0.5, Apache2::AuthCookie 3.18) It does not work with: Ubuntu 14.04 (apache 2.4.7, mod_perl 2.0.8, Apache2::AuthCookie 3.20)

The second setup gives the following in the error log:

    failed to resolve handler Example::AuthHandler

when trying to access a page under /testsite/protected/ *after* you have successfully logged in. If you go to /testsite/logout.html to clear the cookie, and then to /testsite/protected/<any>, it still displays the login page successfully.

The test case is so small that I've reproduced it entirely inline below. You can also get it as a 1.5KB tar bundle from https://osl.uoregon.edu/redmine/attachments/download/155/authcookiesite.tgz

I see some fairly old reports here:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666837
https://rt.cpan.org/Public/Bug/Display.html?id=85832

however from the first link, it *looks* like all this should be working with Debian (and hence Ubuntu 14.04 recently derived from it).

I notice that there is a newer version of Apache2::AuthCookie (3.22) available, so I installed that from CPAN. But this changes the error to:

[Wed Jun 25 13:35:26.054231 2014] [perl:error] [pid 17668] [client 10.0.2.2:50801] Can't locate object method "requires" via package "Apache2::RequestRec" at /usr/local/share/perl/5.18.2/Apache2/AuthCookie.pm line 388.\n, referer: http://localhost:8013/testsite/protected/example.html

and indeed, I see no 'requires' member in http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html

Does anybody have any clues they can pass on?

Many thanks,

Brian Candler.

(Code assumes it's unpacked under /var/tmp; if it's somewhere else then change the first line of testsite.conf and setup.pl as appropriate)

==> testsite.conf <==
PerlRequire /var/tmp/setup.pl
PerlModule Example::TestSite
PerlModule Example::AuthHandler
PerlSetVar TestAuthPath /testsite
PerlSetVar TestAuthLoginScript /testsite/login.html

<Location /testsite/>
  ### To recognize logged-in users even outside of protected area:
  #AuthType Example::AuthHandler
  #AuthName TestAuth
  SetHandler perl-script
  PerlResponseHandler Example::TestSite
</Location>

<Location /testsite/protected/>
  AuthType Example::AuthHandler
  AuthName TestAuth
  PerlAuthenHandler Example::AuthHandler->authenticate
  PerlAuthzHandler Example::AuthHandler->authorize
  Require valid-user
</Location>

<Location /testsite/dologin>
  AuthType Example::AuthHandler
  AuthName TestAuth
  PerlResponseHandler Example::AuthHandler->login
</Location>

<Location /testsite/logout.html>
  AuthType Example::AuthHandler
  AuthName TestAuth
</Location>


==> setup.pl <==
use lib qw(/var/tmp);
1;

==> Example/TestSite.pm <==
package Example::TestSite;
use strict;
use warnings;

use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const -compile => qw(OK);
use Example::AuthHandler ();

sub handler {
  my $r = shift;
  $r->content_type('text/html');
  $r->status(200);
  $r->print(<<EOS);
<html><body>
<p>
<a href="/testsite/general.html">General</a> |
<a href="/testsite/protected/example.html">Protected</a> |
<a href="/testsite/logout.html">Logout</a>
</p>
EOS
  if ($r->uri() eq '/testsite/login.html') {
    $r->print(<<EOS);
<p>Please login:</p>

<form action="/testsite/dologin" method="post">
<input type="text" name="credential_0" />
<input type="password" name="credential_1" />
<input type="hidden" name="destination" value="/testsite/protected/success.html" />
<input type="submit" />
</form>
EOS
  }
  elsif ($r->uri() eq '/testsite/logout.html') {
    $r->auth_type->logout($r);
    $r->print("<p>You are logged out, goodbye</p>");
  }
  else {
$r->print("<p>Hello, uri is " . $r->uri() . "</p>\n"); # FIXME: escape html
    if ($r->user) {
      $r->print("<p>You are logged in as " . $r->user . "</p>\n");
    }
    else {
      Example::AuthHandler->recognize_user($r);
      if ($r->user) {
$r->print("<p>(Not protected but I recognize you as ". $r->user . ")</p>\n");
      }
    }
  }
  $r->print(<<EOS);
</body></html>
EOS
  return Apache2::Const::OK;
}

1;

==> Example/AuthHandler.pm <==
package Example::AuthHandler;
use base qw(Apache2::AuthCookie);

sub authen_cred ($$\@) {
  my $self = shift;  # Package name (same as AuthName directive)
  my $r    = shift;  # Apache request object
  my @cred = @_;     # Credentials from login form

  if ($cred[0] eq 'foo' && $cred[1] eq 'bar') {
    return 'abcd1234';
  }
  return undef;
}

sub authen_ses_key ($$$) {
  my ($self, $r, $session_key) = @_;
  if ($session_key eq 'abcd1234') {
    return 'foo';
  }
  return undef;
}

1;

Reply via email to