Apache PerlAuthzHandler并形成POST变量

时间:2015-01-15 22:48:24

标签: apache perl authorization mod-perl

我有一个mod_perl PerlAuthzHandler授权访问Apache2提供的目录。在控制访问方面,它运作良好。

但是,副作用是它似乎阻止POST表单变量可用于受保护位置的PHP应用程序。至少当我注释掉PerlAuthzHandler并重新加载Apache时,PHP应用程序再次运行。我认为Perl或Perl没有继承完整的环境正在发送一个清洁的环境。

是否可以确保授权后PHP应用程序可以使用所有POST变量?


详细

用户身份验证由此框中的simplesamlphp管理,SP和ADFS(IdP)。 simplesamlphp安装的添加是使用PerlAuthzHandler。

Apache配置

相关位置的Apache配置如下所示:

<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>

授权处理程序

授权处理程序检索在设置会话时记录的组成员身份,并与PerlSetVar中的VALID_GROUP_EXPRESSION进行比较:

#! /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 simpleSAMLphp.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} = $group_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;

PHP脚本失败

启用Perl授权时,下面的简单PHP表单不显示任何值。如果我注释掉PerlAuthzHandler行,则$_POST'[submit']$_POST['in1']都会被设置。

<?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;

?>

同样,身份验证(simplesamlphp / ADFS)和授权都按预期工作。例外情况是,在使用授权时,没有$_POST变量可用。

1 个答案:

答案 0 :(得分:1)

解决

经常发生的问题是我自己造成的。 perlmonks.org的一位僧侣指出Perl处理程序包含以下行:

$query = new CGI;

删除它做到了。因为我实际上只是访问但没有改变任何东西,所以没有任何意义,实际上$ query从未使用过。