
Devin.Bougie at cornell
Oct 30, 2009, 9:30 AM
Post #6 of 8
(854 views)
Permalink
|
|
Re: accessing REMOTE_USER through an Apache proxy
[In reply to]
|
|
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-unsubscribe [at] httpd >>>> " from the digest: users-digest-unsubscribe [at] httpd >>>> For additional commands, e-mail: users-help [at] httpd >>>> >>> > > > --------------------------------------------------------------------- > 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-unsubscribe [at] httpd > " from the digest: users-digest-unsubscribe [at] httpd > For additional commands, e-mail: users-help [at] httpd > --------------------------------------------------------------------- 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-unsubscribe [at] httpd " from the digest: users-digest-unsubscribe [at] httpd For additional commands, e-mail: users-help [at] httpd
|