pha has asked for the wisdom of the Perl Monks concerning the following question:

I have a mod_perl PerlAuthzHandler authorizing access to directories served by Apache2. In terms of controlling access it is working well.

A side effect, though, is that it seems to be preventing POST form variables from being available to PHP apps in the protected locations. At least when I comment out the PerlAuthzHandler and reload Apache the PHP app functions again. I think either the full environment is not being inherited by Perl or Perl is sending a cleansed environment on.

Is it possible to ensure that all POST variables are available to the PHP application after authorization?

Here is more information in response to the comments of Anonymous Monk and sundialsvc4.

User authentication is managed by simplesamlphp on this box, the SP, and ADFS, the IdP. The addition to the simplesamlphp installation is the use of PerlAuthzHandler.

Apache configuration

The Apache configuration for the location in question looks like this:

<Location /activity> ErrorDocument 401 "/simplesaml/authmemcookie.php" AuthName "MCLAnet" AuthType Cookie Require valid-user PerlSetvar Auth_memCookie_SessionTableSize "40" PerlAuthzHandler My::simple PerlSetVar VALID_GROUP_EXPR "status-acad or staff-g" </Location>

Authorization handler

The authorization handler retrieves group memberships recorded in setting up the session and compares to a VALID_GROUP_EXPRESSION in the PerlSetVar:

#! /usr/bin/perl package My::simple; # Version 1.0 MCLA CSS use Apache2::Access (); use Apache2::RequestUtil (); # load modules that are going to be used use Data::Dumper; use CGI qw(:standard); use CGI::Cookie; use Cache::Memcached; use PHP::Serialization qw(serialize unserialize); # compile (or import) constants use Apache2::Const -compile => qw(OK FORBIDDEN); $debug=0; $debug_file="/tmp/xxx"; dmp('prerun',('test')); sub handler { my $r = shift; my $user = $r->user; dmp('0 user',$user); # ------------------------ get valid group(s) for this session my $valid_group_expr=$r->dir_config("VALID_GROUP_EXPR"); dmp('1 valid group list',$valid_group_expr); # -- get the session cooke to retrieve the session <ID> $query = new CGI; # fetch existing cookies my %cookies = CGI::Cookie->fetch; # dmp('Cookies',%cookies); my $ID = $cookies{'SimpleSAMLSessionID'}->value; dmp('2 SimpleSAMLSessionID value',$ID); my $SessionID='simpleSAMLphp.session.' . $ID; # -- use the session ID to look up the value of memcached key si +mpleSAMLphp.session.<ID> my $cache = new Cache::Memcached { 'servers' => ['127.0.0.1:11211'], 'compress_threshold' => 10_000, }; # Get the value from cache: my $value = $cache->get($SessionID); # dmp('mamcache value',($value)); # -- use the value data to find the groups my $hashref = unserialize($value); # dmp('mamcache unserialized',($hashref)); my %hash = %{ $hashref }; %hash = % { $hash {'data'}{chr(0) . 'SimpleSAML_Session' . chr(0 +) . 'authData'}{'default-sp'}{'Attributes'} }; my @groups = @ { $hash{'groups'} }; dmp("3 Comparing $valid_group_expr to", \@groups); my $result=evaluate($valid_group_expr,@groups); if ($result) { dmp("this guy oK",$result); return Apache2::Const::HTTP_OK; } dmp("blowing this guy off",$result); $r->log_reason("Not a member of group " . $valid_group_expr); return Apache2::Const::FORBIDDEN; # return Apache2::Const::HTTP_FORBIDDEN; # return Apache2::Const::HTTP_OK; # return Apache2::Const::DECLINED; } # ======================= utility functions # evaluate returns the boolean value of the expression $expr # after substituting membership information in @groups # # valid operators are # # &&, and, AND logical AND # ||, or, OR logical OR # !, NOT, not logical NOT # # expression must be infix and precidence can be indicated by () sub evaluate { my ($expr,@groups)=@_; # print "$expr\n"; # print Dumper(\%group_hash); # operator tokens my %token_hash = ( '(' => '(', ')' => ')', 'AND' => '&&', 'and' => '&&', 'or' => '||', 'OR' => '||', '!' => '!', 'not' => '!', 'NOT' => '!', ) ; # add the group array into the token hash as TRUEs foreach $v (@groups) { $v=~s/ /_/g; $token_hash{$v} = 1; } dmp('merged hash',\%token_hash); # merge the two hashes into %token_hash # foreach my $tkey ( keys %group_hash) { $token_hash{$tkey} = $grou +p_hash{$tkey}; } # print Dumper(\%token_hash); $expr=~s/\(/ ( /g; $expr=~s/\)/ ) /g; $expr=~s/\!/ ! /g; # print "$expr\n"; my @expr_hash=split (/ /,$expr); $expr=''; foreach my $t (@expr_hash) { if ($t ne '') { if (exists ($token_hash{$t})) { $t = $token_hash{$t} } else +{$t = 0;} $expr = $expr . "$t "; } } dmp("expression",$expr); my $result=0; my $assignment="\$result = $expr;"; dmp("assignment",$assignment); eval($assignment); dmp("result",$result); return $result; } # debug dump structure funcion sub dmp { if ($debug == 1) { my ($label,@value) = @_; my $temp = Dumper(@value); open (T, ">>$debug_file"); # || die "Can't open $debug_file: $! +\n"; print T "$label: $temp\n"; close (T); } } 1;

Failing PHP script

The simple PHP form below displays no value when the Perl authorization is enabled. If I comment out the PerlAuthzHandler line both $_POST'submit' and $_POST'in1' are set.

<?php if (isset($_POST['submit'])) { print_r($_POST); } $form=<<<EOT <form name="test" action="y.php" method="post"> <input name="in1"> <input type="submit" name="submit"> </form> EOT; print $form; ?>

Again, authentication (simplesamlphp/ADFS) and authorization both work as expected. The exception is that when authorization is used no $_POST variables are available.

Replies are listed 'Best First'.
Re: Apache PerlAuthzHandler and HTML form POST vars
by Anonymous Monk on Jan 18, 2015 at 23:05 UTC

      Thank you. I have updated my question and I'll look at the link you sent.

Re: Apache PerlAuthzHandler and HTML form POST vars ( no CGI)
by Anonymous Monk on Jan 19, 2015 at 02:21 UTC

    I think this is your problem

    my $r = shift; ... $query = new CGI;

    You're writing an PerlAuthzHandler, your code should only deal with Apache2::... objects directly

      That was it exactly. Shamefully, it was not even used in the script. I am accessing but not changing anything. Simply deleting the line took care of it.

      Many, many thanks.

Re: Apache PerlAuthzHandler and HTML form POST vars
by locked_user sundialsvc4 (Abbot) on Jan 19, 2015 at 00:39 UTC

    I think that it would be most helpful if you could provide more information about exactly how you have configured the various handlers ... and how, exactly, PHP apps are running in “the protected locations.” Since “authorization” is the last of three handlers (the others being Access and Authentication), and all of them (AFAIK ...) are particular to mod_perl which has nada to do with PHP, a more complete description of the complete setup is requested.

    (Or did you simply “say PHP when you meant to say Perl?”)

    I am also a bit confused by your reference to “environment.”   I ordinarily think of this term as referring to “environment variables,” versus the POST data-stream . . . and in any case I agree/think that, if something is bolluxing-up those [POST ...] variables, any one of the handlers could be doing it.

      Thank you. I have updated the question with more information. Yes, I did mean PHP and I was loosely referring to $_POST as "environment variables". This is my first venture in Perl handlers so it is easy to believe that I have caused my own problem.

Re: Apache PerlAuthzHandler and HTML form POST vars
by locked_user sundialsvc4 (Abbot) on Jan 19, 2015 at 02:32 UTC

    Thank you for updating your post.   Much better.

    I will now step aside and listen to the subsequent answers with great interest, as I am dealing with vaguely-similar issues right now, too.

    (And, P.S. ... how about actually logging in before replying, folks ... and maybe being a wee bit less cryptic in those replies?   AtDhVaAnNkCsE ... == “thanks in advance.” )

    One thing that I am curious about, and truly do not myself know the answer to, is:   “does it actually work to provide only an ‘authorization’ handler, in the absence of the other two?”   Particularly in the absence of an “authentication” handler?   (i.e. “if you do not know who I am, how do you know that I am authenticated to do anything?”)   Does this “authorization” handler as-presented by the OP do an appropriate thing, or too much or too little?   Does it need to be more-than-one handler?

    I am an interested-party along with the OP ... not in a position to answer the question, but also-interested in what the answer is.

      With the deletion of the bogus line below all is right with the world.

      # $query = new CGI

      To your expressed interest, does my experience shed any light? My handler depends on the ability to find a cookie and retrieve information from memcache none of which involves mod_perl bits in other phases. Seems not to be bothered by that lack.

      Thanks again for you response.