You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by "Kreimendahl, Chad J" <Ch...@umb.com> on 2004/06/30 00:01:30 UTC

potential bug/issue with internal_redirect in mp2

Here goes...

-------------8<---------- Start Bug Report ------------8<----------

1. Problem Description:

 This issue occurs only when using auth and internal_redirects.   

 User request page a.html
 some task is done and redirects to b.html
 the redirect page (b.html) will not contain $r->user unless
get_basic_auth_pw is checked first

        odd (not sure why)... here's how I had it and what I did to fix
it.


        OLD WAY: [broken]
        $obj->{USER_ID} = $r->user;
        $obj->{USER_PASS} = $I->get_basic_auth_pw;

        NEW WAY: [fixed]
        $obj->{USER_PASS} = $r->get_basic_auth_pw;
        $obj->{USER_ID} = $r->user;


 So anyway, the only way I figured this out is because I put debugging
on just about every var through the app, and I notice that my USER_ID
one was the only one that changed (from the user who was on to undef).
well, I decided to warn out $r->user later on ... and after moving it
closer and closer to where I put it in my object, I noticed that it's
not assigned 'til immediately after get_basic_auth_pw.

Meaning: The problem is that $r->user will not return the proper user id
in an internal_redirect without first calling get_basic_auth_pw (which
i'm guessing not too many do)... 

Hope this helps, any chance on a fix for this?



  
2. Used Components and their Configuration:

*** mod_perl version 1.9914

*** using
/var/tmp/src/apache/apache2/mod_perl-1.99_14/lib/Apache/BuildConfig.pm
*** Makefile.PL options:
  MP_APXS         => /usr/local/apache2/bin/apxs
  MP_COMPAT_1X    => 1
  MP_GENERATE_XS  => 1
  MP_INST_APACHE2 => 1
  MP_LIBNAME      => mod_perl
  MP_USE_DSO      => 1
  MP_USE_STATIC   => 1


*** httpd -V
Server version: Apache/2.0.49
Server built:   Jun  1 2004 14:59:01
Server's Module Magic Number: 20020903:7
Architecture:   32-bit
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/worker"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_PROC_PTHREAD_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

*** perl -v (it's perl 5.8.4 using threading on solaris... )

*** Packages of interest status:

Apache::Request: 2.03-dev
CGI            : 3.05
LWP            : 5.79
mod_perl       : 1.29, 1.9914


-------------8<---------- End Bug Report --------------8<----------

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: potential bug/issue with internal_redirect in mp2

Posted by Geoffrey Young <ge...@modperlcookbook.org>.

John Wittkoski wrote:
> Geoffrey Young wrote on 6/29/04, 6:28 PM:
>  >
>  > >         OLD WAY: [broken]
>  > >         $obj->{USER_ID} = $r->user;
>  > >         $obj->{USER_PASS} = $I->get_basic_auth_pw;
>  >
>  > I'm not sure where you would have gotten this way from, but it is clearly
>  > wrong - in both apache 1.3 and 2.0 it is ap_get_basic_auth_pw that
>  > populates
>  > $r->user (r->user in 2.0 and r->connection->user in 1.3).
>  >
>  > >         NEW WAY: [fixed]
>  > >         $obj->{USER_PASS} = $r->get_basic_auth_pw;
>  > >         $obj->{USER_ID} = $r->user;
>  >
>  > yes, this has always been the correct way.

> 
> Sorry, I know this thread is from a few weeks back, but I'm a little 
> behind (as usual) and I wanted to ask for clarification.

no problem :)

> 
> Isn't the ordering issue mentioned above only critical if you are coding 
> your own authentication handler? 

yes.  that was the assumption I made.

> (I don't know why you'd call 
> get_basic_auth_pw outside of an authentication handler, but you might 
> need to call $r->user outside of one.) 

exactly why I assumed we were talking about an authentication handler.
after authentication the user is authenticated, so there is generally no
reason why you would want the password again.  I mean, I suppose you might,
but I can't see why if your application is designed well.

> If the current request was 
> already handled by the built in Basic (or other basic password using) 
> authentication handler, didn't that handler already call 
> get_basic_auth_pw, so $r->user is populated for the remainder of that 
> request?

yes, that's right.

> 
> I ask because we have code that runs in a post-authentication phase that 
> calls $r->user and it's always there, even for subrequests.

it would be, but only after _somebody_ calls get_basic_auth_pw().

> 
> That being said, I did notice that a few of the Apache::Auth* modules 
> (that use the Basic auth mechanism to get the password) use 
> is_initial_req to short circuit the authentication phase for 
> sub-requests before they call get_basic_auth_pw, resulting in $r->user 
> not being populated for post-authentication phases of subrequests unless 
> they call it themselves. (Under 2.0 that is, since under 1.3 this is 
> masked by the clever bug you mention.)

yup.  I've never been entirely convinced that short-circuiting
authentication in subrequests is a good idea.  at first, people were
returning DECLINED, an idea that started someplace (I'm not sure where) but
that we propagated in the cookbook.  after the cookbook was published I
realized that was most certainly a bad idea - if you DECLINED then mod_auth
will kick in, so in order to pass auth for the subrequest you would need an
AuthUserFile, as mod_auth has no such special subrequest handling.

some folks choose to return OK, which has the effect you mentioned, namely
that $r->user will not be set for subrequests (in 2.0 at least).  I think I
said someplace in the cookbook that using $r->is_initial_req to shortcircuit
subrequest logic isn't for everyone, that you'll need to decide what works
for your application.  clearly, if you rely on $r->user within those
subrequests you'll need to either skip the $r->is_initial_req logic, or
always look for $r->user in the main request.  that is, something like

  my $user = ($r->prev || $r)->user();
  # or
  my $user = $r->main->user();

HTH

--Geoff

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: potential bug/issue with internal_redirect in mp2

Posted by John Wittkoski <jo...@aol.com>.
Geoffrey Young wrote on 6/29/04, 6:28 PM:
 >
 > >         OLD WAY: [broken]
 > >         $obj->{USER_ID} = $r->user;
 > >         $obj->{USER_PASS} = $I->get_basic_auth_pw;
 >
 > I'm not sure where you would have gotten this way from, but it is clearly
 > wrong - in both apache 1.3 and 2.0 it is ap_get_basic_auth_pw that
 > populates
 > $r->user (r->user in 2.0 and r->connection->user in 1.3).
 >
 > >         NEW WAY: [fixed]
 > >         $obj->{USER_PASS} = $r->get_basic_auth_pw;
 > >         $obj->{USER_ID} = $r->user;
 >
 > yes, this has always been the correct way.
 >
 > subrequests (of which internal_redirect is one) have a rather clever
 > bug in
 > 1.3 - r->connection->user is global to the entire request, which includes
 > any subrequests.  so, the "OLD WAY" would have worked for subrequests
 > in 1.3
 > (though it should not have worked for the main request).  see a post
 > from me
 > last week for more details on this exact issue.
 >
 > at any rate, this is not a mod_perl bug, or even a mod_perl feature -
 > it's a
 > feature of the apache API and there is nothing mod_perl can do about it.
 >
 > but thanks for bringing it up :)
 >


Sorry, I know this thread is from a few weeks back, but I'm a little 
behind (as usual) and I wanted to ask for clarification.

Isn't the ordering issue mentioned above only critical if you are coding 
your own authentication handler? (I don't know why you'd call 
get_basic_auth_pw outside of an authentication handler, but you might 
need to call $r->user outside of one.) If the current request was 
already handled by the built in Basic (or other basic password using) 
authentication handler, didn't that handler already call 
get_basic_auth_pw, so $r->user is populated for the remainder of that 
request?

I ask because we have code that runs in a post-authentication phase that 
calls $r->user and it's always there, even for subrequests.

That being said, I did notice that a few of the Apache::Auth* modules 
(that use the Basic auth mechanism to get the password) use 
is_initial_req to short circuit the authentication phase for 
sub-requests before they call get_basic_auth_pw, resulting in $r->user 
not being populated for post-authentication phases of subrequests unless 
they call it themselves. (Under 2.0 that is, since under 1.3 this is 
masked by the clever bug you mention.)


    --John






-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: potential bug/issue with internal_redirect in mp2

Posted by Geoffrey Young <ge...@modperlcookbook.org>.
>         OLD WAY: [broken]
>         $obj->{USER_ID} = $r->user;
>         $obj->{USER_PASS} = $I->get_basic_auth_pw;

I'm not sure where you would have gotten this way from, but it is clearly
wrong - in both apache 1.3 and 2.0 it is ap_get_basic_auth_pw that populates
$r->user (r->user in 2.0 and r->connection->user in 1.3).

>         NEW WAY: [fixed]
>         $obj->{USER_PASS} = $r->get_basic_auth_pw;
>         $obj->{USER_ID} = $r->user;

yes, this has always been the correct way.

subrequests (of which internal_redirect is one) have a rather clever bug in
1.3 - r->connection->user is global to the entire request, which includes
any subrequests.  so, the "OLD WAY" would have worked for subrequests in 1.3
(though it should not have worked for the main request).  see a post from me
last week for more details on this exact issue.

at any rate, this is not a mod_perl bug, or even a mod_perl feature - it's a
feature of the apache API and there is nothing mod_perl can do about it.

but thanks for bringing it up :)

--Geoff

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html