Cannot retrieve Apache environment variables in PHP
Asked Answered
S

4

6

Background

I have an Apache/2.2.15 (Win32) with PHP/5.3.2 set up, handling authentication.

<Directory /usr/www/myhost/private>
  # core authentication and mod_auth_basic configuration
  # for mod_authn_dbd
  AuthType Basic
  AuthName "My Server"
  AuthBasicProvider dbd

  # core authorization configuration
  Require valid-user

  # mod_authn_dbd SQL query to authenticate a user
  AuthDBDUserPWQuery "SELECT Password,UserName,Realm,Access FROM authn WHERE user = %s"
</Directory>

The authentication works fine! No problems.

But regarding to the documentation, any extra field returned back from the AuthDBDUserPWQuery will be put into an AUTHENTICATION_fieldname variable in the Environment.

With phpinfo(), I can see these variables with he correct values under "Apache Environment".

AUTHENTICATE_USERNAME
AUTHENTICATE_REALM
AUTHENTICATE_ACCESS

Problem

I can't fetch those environment variables from my php.

1 <?php
2   $Access = apache_getenv('AUTHENTICATE_ACCESS',true);
3   var_dump($Access);
4 ?>

Line 3 prints bool(false) indicating that the variable wasn't found!
However if I change to another Apache Environment variable such as 'HTTP_HOST' it works.
..and yes, I have tried getenv() also, same result.

There is also a note that the Apache server needs to be compiled with APR 1.3.0 to work. I used the Apache msi build from httpd.apache.org and it seems to be compiled with APR above version 2. Since I can see them with phpinfo() they must be accessible from PHP.

Spinach answered 29/11, 2010 at 22:48 Comment(4)
[♦ note: See revision history for context of this comment.] We usually don't flame about someone's english (yours is pretty good) and if your code formatting sucked somebody would probably edit it so it's well-readable. Additionally SO is not the place where people are told to google/rtfm - googling/rtfming is what the people answering might do as they'll get +rep for it while telling your to do so would most likely result in -rep. :pRosenblast
I don't have any answers to your question, but +1 for having the best structured question I have ever seen on SO.Deflation
Perfectly valid question, no need to be so defensive. :) RTFM answers are usually reserved for much, much worse (non-)questions.Millenary
Well, thanks for the points :D Sorry for sounding a bit harsh, but I have way too much experience in my life of people not understanding the question and instead complains about spelling to get up their post rating. I will keep in mind that OS are different from the past experiences :)Spinach
S
2

I made a work around,

It seems like this might be a PHP bug. Found some related bugs reported for PHP 4 and maybe they haven't fixed them yet...

I did a solution that I really don't like (because I'm accessing the Apache userdata table), but it seems that I have no choice.

//************************************************************* 
// If PHP failed to retrieve the AuthDBDUserPWQuery fields.
// Connect to Apache authentication databaseand create the
// envirnment variables manually
//
if (empty($_ENV['AUTHENTICATE_ACCESS'])) {
  $Apache = mysql_connect('MyServerIP','MyUserName','MyPassword',false,MYSQL_CLIENT_SSL|MYSQL_CLIENT_COMPRESS);
  mysql_select_db('MyDatabase',$Apache);
  $SQLSet = mysql_query("SELECT Realm, Access FROM authenticationtable WHERE UserName='".$_SERVER['PHP_AUTH_USER']."' AND Password='".$_SERVER['PHP_AUTH_PW']."'");
  $SQLRow = mysql_fetch_array($SQLSet);
  $_ENV['AUTHENTICATE_REALM'] = $SQLRow['Realm'];
  $_ENV['AUTHENTICATE_ACCESS']= $SQLRow['Access'];
  mysql_close($Apache);
}

If PHP has failed to update $_ENV correct, this will retrieve the current logged in user from the same database and table that Apache is using for authentication. Then the extra fields will be written into the global $_ENV variable so it can be used as it is supposed. Later when the "bug" is fixed, it will automatically use the original $_ENV.

If anyone can bring some up to date information on this topic, I would be happy...

Spinach answered 30/11, 2010 at 2:23 Comment(1)
And how can this be down woted?!? I found a solution to my own questione and posted it so others can see it. If you are going to down vote, please state why?!?Spinach
M
3

I have used this mod_rewrite rule in an .htaccess file to make the HTTP Authorization header environment variable available in $_SERVER['HTTP_AUTHORIZATION']. I'm sure this could be adapted for your purposes. Not sure if it's the best solution, but it's a solution:

RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
Millenary answered 30/11, 2010 at 0:19 Comment(2)
+1 for trying :D I had to read up on RewriteRule to understand what you suggested. But I don't think this will work. If I understand this right %{HTTP:Authorization} is already present in your HTTP header and you only "copy" the information to the Apache environment. In my case AuthDBDUserPWQuery creates "Apache environment" variables for each extra field (after password) from the SQL statement. These values are not present anywhere else. Can this be a bug in PHP that only predefined Apache variables can be retrieved?Spinach
@Max Hmm, I see... I don't have anything else, unfortunately.Millenary
S
2

I made a work around,

It seems like this might be a PHP bug. Found some related bugs reported for PHP 4 and maybe they haven't fixed them yet...

I did a solution that I really don't like (because I'm accessing the Apache userdata table), but it seems that I have no choice.

//************************************************************* 
// If PHP failed to retrieve the AuthDBDUserPWQuery fields.
// Connect to Apache authentication databaseand create the
// envirnment variables manually
//
if (empty($_ENV['AUTHENTICATE_ACCESS'])) {
  $Apache = mysql_connect('MyServerIP','MyUserName','MyPassword',false,MYSQL_CLIENT_SSL|MYSQL_CLIENT_COMPRESS);
  mysql_select_db('MyDatabase',$Apache);
  $SQLSet = mysql_query("SELECT Realm, Access FROM authenticationtable WHERE UserName='".$_SERVER['PHP_AUTH_USER']."' AND Password='".$_SERVER['PHP_AUTH_PW']."'");
  $SQLRow = mysql_fetch_array($SQLSet);
  $_ENV['AUTHENTICATE_REALM'] = $SQLRow['Realm'];
  $_ENV['AUTHENTICATE_ACCESS']= $SQLRow['Access'];
  mysql_close($Apache);
}

If PHP has failed to update $_ENV correct, this will retrieve the current logged in user from the same database and table that Apache is using for authentication. Then the extra fields will be written into the global $_ENV variable so it can be used as it is supposed. Later when the "bug" is fixed, it will automatically use the original $_ENV.

If anyone can bring some up to date information on this topic, I would be happy...

Spinach answered 30/11, 2010 at 2:23 Comment(1)
And how can this be down woted?!? I found a solution to my own questione and posted it so others can see it. If you are going to down vote, please state why?!?Spinach
M
0

There is a clue in deceze's answer. He is fetching the data from $_SERVER instead of $_ENV.

I was setting a Apache Env Var with

SenEnv MY_VAR "true" in the main httpd.conf and couldn't see it in $_ENV. It was in $_SERVER though.

Mckie answered 1/3, 2011 at 20:54 Comment(0)
A
0

Recently i wrote a library to get values from environment variables and parse to the PHP data types. This library can be used to parse environment variables to PHP data types (like the casting to integer, float, null, boolean), parse the complex data structures like a JSON string and more with the contribution of the commnunity.

The library is available here: https://github.com/jpcercal/environment

Setup your environment variables with .htaccess by example:

SetEnv YOUR_ENV_VARIABLE_NAME the-value-of-your-env-var

And to get the values from environment variable (independently of the environment CLI, Apache, Nginx, PHP Built-in Server and more) to do it:

<?php
// ...
require "vendor/autoload.php";
// ...
var_dump(Cekurte\Environment\Environment::get("YOUR_ENV_VARIABLE_NAME"));

Enjoy it.

Aide answered 4/11, 2015 at 20:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.