Hi André,
Thank you very much for another thorough explanation. This certainly
does help clear up my confusion. With the latest posted
configuration, I am able to see the REMOTE_USER HTTP header from the
backend GlassFish Web Application (using HttpServletRequest.getHeader
("REMOTE_USER")). As you explain, HttpServletRequest.getRemoteUser
and getUserPrincipal both return null because they are looking for the
REMOTE_USER cgi-bin environment variable.
For what it's worth, here is an excerpt from the CGI script I was
testing with. When calling the script directly, $REMOTE_USER is set
but $HTTP_REMOTE_USER is not. When accessing the script through the
proxy (using the latest posted configuration), $HTTP_REMOTE_USER is
set but $REMOTE_USER is not.
------
# test for $REMOTE_USER
if [ -z "$REMOTE_USER" ]; then
echo '$REMOTE_USER not set.'
else echo "REMOTE_USER is $REMOTE_USER"
fi
# test for $HTTP_REMOTE_USER
if [ -z "$HTTP_REMOTE_USER" ]; then
echo '$HTTP_REMOTE_USER not set.'
else echo "HTTP_REMOTE_USER is $HTTP_REMOTE_USER"
fi
echo ''
echo 'Environment is:'
printenv
------
I believe being able to access the REMOTE_USER HTTP header achieves
our goal. Thank you very much for all of your time and help.
Sincerely,
Devin
I still have some lingering doubt about whether there is not a
confusion somewhere between
- the Apache process's environment values (what it gets in its own
environment when it starts up)
- the Apache "internal environment variables" (set internally by
Apache, for Apache only, during one request), which when using the
mod_jk connector to forward requests to Tomcat via AJP, become known
as "request attributes" (a better name, in my opinion, less confusing)
- HTTP request headers and their content
- cgi-bin environment values (set by Apache in the environment of a
child process just prior to running the cgi program in it).
All these things above are distinct animals. Apache does for
instance take the value of /some/ HTTP request headers, and
translates them into /some/ environment values for cgi-bin programs,
but the HTTP request headers and cgi-bin environment values are
distinct items, and there is not a one-to-one relationship between
them. They do not even necessarily have the same name.
It took me a while to "click" on this, but I believe that what you
are seeing with your cgi-bin script is :
- your Apache setup sets a HTTP Header "REMOTE_USER", and proxies
that modified request
- the request is received by (another instance of) Apache, which
calls a cgi-bin script to handle it.
- prior to calling the cgi-bin script, Apache picks up the content
of the HTTP header named "REMOTE_USER", and sets up that content as
a *cgi-bin environment variable* named "HTTP_REMOTE_USER".
- then in your cgi script, you are not looking at the HTTP header
"REMOTE_USER" (which was received by Apache), but you are looking
for an *environment variable* "REMOTE_USER", which is not there.
It is not there because the cgi-bin environment variable (as set by
Apache) is named "HTTP_REMOTE_USER".
Get the difference ?
A cgi-bin script does not, in general, have access to the HTTP
headers that came in with the request which caused Apache to run
this cgi-bin script.
Instead, Apache "translates" *some* of these request HTTP headers
into cgi-bin environment variables, to which the cgi-bin program
*does* have access.
(For example, Apache also splits off the query-string part of the
request URL, and passes it to the cgi-bin program as the environment
variable QUERY_STRING. But that was never a HTTP request header.)
- But when you are going to pass this request to Glassfish, Apache
is not going to set up environment values for Glassfish. It is
going to pass HTTP headers. And one of them *will* be "REMOTE_USER:".
So in fact you have already solved your problem.
You are just testing it with the wrong tool.
If your Apache server is set up with mod_perl, I could give you a
Perl cgi-bin script which would show you the difference.
That's because under mod_perl, Perl cgi-bin scripts *can* ask Apache
for the original HTTP request headers.
Devin Bougie wrote:
I have tried a different approach by moving the RewriteRules into
the Location directive. With this configuration, the
HTTP_REMOTE_USER variable is set and visible by the backend script
and application. However, REMOTE_USER is still blank. Here is the
alternate configuration:
------
<Location "/test">
order deny,allow
deny from all
AuthType KerberosV5
AuthName "W4restrict"
KrbDefaultInstance net
Satisfy any
require valid-user
RewriteEngine on
RewriteCond %{REMOTE_USER} (.+)
RequestHeader Set Proxy-ip %{REMOTE_ADDR}e
RequestHeader Set Host ourserver.com:443
RequestHeader set REMOTE_USER %{REMOTE_USER}e
RewriteRule ^/var/www/html/test/(.*) http://localhost/cgi-bin/test/$1
[P,L,E=REMOTE_USER:%{REMOTE_USER}]
</Location>
------
And here is what we see in rewrite.log:
------
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (3) [per-dir /test/] add path info postfix: /var/www/html/test -
> /var/www/html/test/remote.cgi
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (3) [per-dir /test/] applying pattern '^/var/www/html/test/(.*)'
to uri '/var/www/html/test/remote.cgi'
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (4) RewriteCond: input='dab66' pattern='(.+)' => matched
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (2) [per-dir /test/] rewrite /var/www/html/test/remote.cgi -> http://localhost/cgi-bin/test/remote.cgi
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (5) setting env variable 'REMOTE_USER' to 'dab66'
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (2) [per-dir /test/] forcing proxy-throughput with http://localhost/cgi-bin/test/remote.cgi
192.168.213.159 - dab66 [29/Oct/2009:11:04:47 --0400] [ourserver.com/sid#8885358][rid#971a7d0/initial
] (1) [per-dir /test/] go-ahead with proxy request proxy:http://
localhost/cgi-bin/test/remote.cgi [OK]
------
Any suggestions for passing REMOTE_USER through an Apache proxy
would be greatly appreciated.
Many Thanks,
Devin
On Oct 28, 2009, at 4:03 PM, Devin Bougie wrote:
... For what it's worth, I have tried inserting a RewriteCond to
make sure the proxy only occurs when REMOTE_USER is set. This
cleaned up the rewrite.log file a bit, but the script is still not
able to see REMOTE_USER. Here is our updated configuration and
rewrite.log.
------
######
# GlassFish proxy
ProxyPreserveHost on
RewriteEngine on
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteLog /var/log/httpd/rewrite.log
RewriteLogLevel 9
RequestHeader Set Proxy-keysize 512
RequestHeader Set Proxy-ip %{REMOTE_ADDR}e
RequestHeader Set Host ourserver.com:443
RequestHeader set REMOTE_USER %{LA-U:REMOTE_USER}e
RewriteRule ^/test$ /test/ [R,L]
RewriteRule ^/test/(.*) http://localhost/cgi-bin/test/$1
[P,L,E=REMOTE_USER:%{LA-U:REMOTE_USER}]
<Location "/test">
order deny,allow
deny from all
AuthType KerberosV5
AuthName "kerberos authentication"
Satisfy any
require valid-user
</Location>
------
... [rid#8e23fc0/initial] (2) init rewrite engine with requested
uri /test/remote.cgi
... [rid#8e23fc0/initial] (3) applying pattern '^/test$' to uri '/
test/remote.cgi'
... [rid#8e23fc0/initial] (3) applying pattern '^/test/(.*)' to
uri '/test/remote.cgi'
... [rid#8e23fc0/initial] (2) rewrite /test/remote.cgi ->
http://localhost/cgi-bin/test/remote.cgi
... [rid#8e38648/subreq] (2) init rewrite engine with requested
uri /test/remote.cgi
... [rid#8e38648/subreq] (1) pass through /test/remote.cgi
... [rid#8e23fc0/initial] (5) lookahead: path=/test/remote.cgi
var=REMOTE_USER -> val=dab66
... [rid#8e23fc0/initial] (5) setting env variable 'REMOTE_USER'
to 'dab66'
... [rid#8e23fc0/initial] (2) forcing proxy-throughput with
http://localhost/cgi-bin/test/remote.cgi
... [rid#8e23fc0/initial] (1) go-ahead with proxy request
proxy:http://localhost/cgi-bin/test/remote.cgi [OK]
------
Our end goal is to proxy from the Apache server to a GlassFish
Enterprise Server. Just for reference, here is the rewrite.log
for a request that's proxied to a GlassFish Web Application.
------
... [rid#8e23fc8/initial] (2) init rewrite engine with requested
uri /HelloWeb/UserServlet
... [rid#8e23fc8/initial] (3) applying pattern '^/HelloWeb$' to
uri '/HelloWeb/UserServlet'
... [rid#8e23fc8/initial] (3) applying pattern '^/HelloWeb/(.*)'
to uri '/HelloWeb/UserServlet'
... [rid#8e23fc8/initial] (2) rewrite /HelloWeb/UserServlet ->
http://localhost:38080/HelloWeb/UserServlet
... [rid#8e1ffb8/subreq] (2) init rewrite engine with requested
uri /HelloWeb/UserServlet
... [rid#8e1ffb8/subreq] (1) pass through /HelloWeb/UserServlet
... [rid#8e23fc8/initial] (5) lookahead: path=/HelloWeb/
UserServlet var=REMOTE_USER -> val=dab66
... [rid#8e23fc8/initial] (5) setting env variable 'REMOTE_USER'
to 'dab66'
... [rid#8e23fc8/initial] (2) forcing proxy-throughput with
http://localhost:38080/HelloWeb/UserServlet
... [rid#8e23fc8/initial] (1) go-ahead with proxy request
proxy:http://localhost:38080/HelloWeb/UserServlet [OK]
------
Any suggestions would be greatly appreciated.
Thank you again,
Devin
On Oct 28, 2009, at 11:15 AM, André Warnier wrote:
Devin Bougie wrote:
...
Hi.
I'll give you my interpretation, after looking at the log, not
really at the configuration.
I think the confusion may be about when and where, things happen
exactly. And it is not really helped by your choice to proxy from
your server to itself..
If you examine the log below, you will see different/distinct
requests, identified by their respective "rid" number.
The first is the request rid#8aa28f8 that comes in originally, on
your "first" server (before the proxying occurs).
That one does the proxying before your <Location /test> is even
invoked (in my opinion). So at that point, the authentication
has not even happened, and REMOTE_USER is undefined or empty.
That request, you then proxy to your "second" server.
Now the proxied request comes in to your "second" server. That is
request rid#8aa8908. That one starts without a REMOTE_USER (see
above), but then goes through the <Location> section, where it
acquires an id.
But by then it is too late for proxying..
It would all probably be clearer if you set this up in two
distinct VirtualHosts, and proxied from the first to the second.
Another thing, is that Apache "environment variables", are kind
of "virtual", in the sense that they exist inside of Apache, for
the duration of one request.
When you proxy something to another server, this is a new
request, and this other server does not magically inherit the
environment of your first request in the first server.
To pass it on, you would have to set it in a header which you
pass to the second server. But then, you must have a value to
pass, by the time you create the header.
Which does not seem to be the case here.
Hope that is clear.
As for me, I think I need a cup of coffee now.
------
######
# GlassFish proxy
ProxyPreserveHost on
RewriteEngine on
RewriteLog /var/log/httpd/rewrite.log
RewriteLogLevel 9
RequestHeader Set Proxy-keysize 512
RequestHeader Set Proxy-ip %{REMOTE_ADDR}e
RequestHeader Set Host ourserver.com:443
RequestHeader set REMOTE_USER %{LA-U:REMOTE_USER}e
RewriteRule ^/test$ /test/ [R,L]
RewriteRule ^/test/(.*) http://localhost/cgi-bin/test/$1
[P,L,E=REMOTE_USER:%{LA-U:REMOTE_USER}]
<Location "/test">
order deny,allow
deny from all
AuthType KerberosV5
AuthName "kerberos authentication"
Satisfy any
require valid-user
</Location>
------
And here is what I see in rewrite.log. REMOTE_USER is
eventually set properly, just not soon enough for the script.
------
... [rid#8aa28f8/initial] (2) init rewrite engine with requested
uri /test/remote.cgi
... [rid#8aa28f8/initial] (3) applying pattern '^/test$' to uri
'/test/remote.cgi'
... [rid#8aa28f8/initial] (3) applying pattern '^/test/(.*)' to
uri '/test/remote.cgi'
... [rid#8aa28f8/initial] (2) rewrite /test/remote.cgi ->
http://localhost/cgi-bin/test/remote.cgi
... [rid#8aa4900/subreq] (2) init rewrite engine with requested
uri /test/remote.cgi
... [rid#8aa4900/subreq] (1) pass through /test/remote.cgi
... [rid#8aa28f8/initial] (5) lookahead: path=/test/remote.cgi
var=REMOTE_USER -> val=
... [rid#8aa28f8/initial] (5) setting env variable 'REMOTE_USER'
to ''
... [rid#8aa28f8/initial] (2) forcing proxy-throughput with
http://localhost/cgi-bin/test/remote.cgi
... [rid#8aa28f8/initial] (1) go-ahead with proxy request
proxy:http://localhost/cgi-bin/test/remote.cgi [OK]
... [rid#8aa8908/initial] (2) init rewrite engine with requested
uri /test/remote.cgi
... [rid#8aa8908/initial] (3) applying pattern '^/test$' to uri
'/test/remote.cgi'
... [rid#8aa8908/initial] (3) applying pattern '^/test/(.*)' to
uri '/test/remote.cgi'
... [rid#8aa8908/initial] (2) rewrite /test/remote.cgi ->
http://localhost/cgi-bin/test/remote.cgi
... [rid#8abcf90/subreq] (2) init rewrite engine with requested
uri /test/remote.cgi
... [rid#8abcf90/subreq] (1) pass through /test/remote.cgi
... [rid#8aa8908/initial] (5) lookahead: path=/test/remote.cgi
var=REMOTE_USER -> val=dab66
... [rid#8aa8908/initial] (5) setting env variable 'REMOTE_USER'
to 'dab66'
... [rid#8aa8908/initial] (2) forcing proxy-throughput with
http://localhost/cgi-bin/test/remote.cgi
... [rid#8aa8908/initial] (1) go-ahead with proxy request
proxy:http://localhost/cgi-bin/test/remote.cgi [OK]
------
Any suggestions would be greatly appreciated. Please let me
know if there is any more information I can provide.
Many thanks,
Devin
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server
Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscr...@httpd.apache.org
" from the digest: users-digest-unsubscr...@httpd.apache.org
For additional commands, e-mail: users-h...@httpd.apache.org
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server
Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscr...@httpd.apache.org
" from the digest: users-digest-unsubscr...@httpd.apache.org
For additional commands, e-mail: users-h...@httpd.apache.org
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscr...@httpd.apache.org
" from the digest: users-digest-unsubscr...@httpd.apache.org
For additional commands, e-mail: users-h...@httpd.apache.org