Apache httpd mod_headers disobedience - apache

I have a client sending basic authentication credentials in a header named "Basic authentication", instead of the correct "Authorization". I can't fix the client, so I'm trying to work around the problem on the server.
This works and sets the "X-Authorization" header to whatever value was sent by the client in the "Basic authentication" header:
SetEnvIf ^Basic.authentication$ ^(.*)$ fixauth=$1
RequestHeader set X-Authorization %{fixauth}e env=fixauth
This sets the environment variable fixauth, but then RequestHeader does nothing:
SetEnvIf ^Basic.authentication$ ^(.*)$ fixauth=$1
RequestHeader set Authorization %{fixauth}e env=fixauth
Using "RequestHeader add" makes no difference. It looks as if mod_header would be refusing to touch the Authorization header, but there is nothing about it in the documentation and nothing that I could find in the source code.
What exactly is the problem? Why does setting X-Authorization work, but setting Authorization does not?

Related

Apache2 - Rewrite Response header Key

How can I rewrite response headers within the apache2 conf? Is this even possible?
We are using apache2 for legacy services which connects to a service behind an envoy proxy.
Envoy always set the response and request header to lower-case. Their solution with
preserve case format doesn't work, because they don't respect the source header.
I expect a responseheader like
"DockingStation_One: 44"
envoy does
"dockingstation_one: 44"
with their preserve case format i get
"Dockingstation_one: 44"
My idea was to rewrite the header either with mod_rewrite or mod_headers in apache2 before it send the response to the client. Sadly nothing works as expected.
My latest setting:
<Location /my/service/v2>
RewriteEngine on
# 1. Save the current value in env var (Case of header name does not matter)
SetEnvIf dockingstation_one(.*) HEADER_VALUE=$1
# 2. Delete the current header (Case of header name does not matter)
Header unset "dockingstation_one" env=HEADER_VALUE
# 3. Recreate header with the required case (Case of header name is preserved)
# env=HEADER_VALUE ensures the header is only set if it was set to begin with
Header set "DockingStation_One" %{DOCKINGSTATION_ONE}e env=HEADER_VALUE
ProxyPass "http://service.go:8090/v2"
ProxyPassReverse "http://service.go:8090/v2"
</Location>
Nevermind. My whole syntax was wrong. My fix looks like this:
Header always set "DockingStation_One" "expr=%{resp:dockingstation_one}"

Apache- trying to add Authentication header to proxy request

We have an Angular app hosted on Apache that is going through QA testing. The app communicates with an app server hosting our web services via a reverse proxy setup in Apache's httpd.conf:
ProxyPass /SVCS/ https://dev.mycompany.test/SVCS/
ProxyPassReverse /SVCS/ https://devws.mycompany.test/SVCS/
We noticed the original developer hard-coded the Basic Auth header the downstream web services require in the JavaScript. We want to remove this from the web app and instead have Apache append the Basic Auth header in the proxied request.
<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin: "*"
Header set Access-Control-Allow-Methods: "OPTIONS, GET"
Header set Access-Control-Max-Age: 1
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Headers: "authorization, X-my-header, X-your-header"
RequestHeader set Authorization "Basic FOOBAR123ZZZZZZZZZZZZZZZZZZZZZ="
</IfModule>
This IfModule snippet was already in the file, I just added the RequestHeader line (obfuscated here). As soon as this is added, the browser starts prompting for a username/password "Authentication Required". I tried setting the Access-Control-Allow-Credentials=false but there was no effect. The Basic auth user/password is a service account created for the app to access the web services, we don't want the end user to have to enter anything, they are already authenticated via SSO from another app.
How can I get the basic auth added to the proxied request's headers and not prompt the user for a password?
I tried something along the lines of this post apache-basic-authentication-issue-with-reverse-proxy which essentially configures a password file. But that wasn't working, even when entering the correct password the service was returning a 401 not authorized (plus I don't want the user to have to enter anything)
The authentication prompt was due to the fact I was setting the Authentication header for ALL requests instead of just the one service that required it. There was a followup service called that if I add the Auth header to, the server was complaining about the Authentication. I was able to narrow the setting of the header to this service only (via RewriteCond and RewriteRule) and all is well.

Concatenate environment variable in Apache RequestHeader

Background: I am trying to set an Authorization header from my Apache VirtualHost config when a JWT is sent as a query parameter.
I am really close to getting this to work, but I have run into one final issue. The header must be in the form of:
Authorization: Bearer token
Here is the relevant config I have so far:
RewriteCond %{QUERY_STRING} jwt=(.*)
RewriteRule ^(.*)$ - [env=JWT:%1]
RequestHeader setifempty Authorization "Bearer %{JWT}e"
It ALMOST works, however, the header is set like so:
Authorization: ('Bearer ' 'token')
How can I make it so that the value of the header is concatenated into a single string without the parentheses and separate strings?

Using mod_rewrite to extract request headers before authentication

I need to rewrite a URL to copy an authentication token from the URL into a header (because a new client can't use headers), and remove the (large) token from the URL.
<Location /foo/>
RewriteEngine On
RewriteRule ^(.*)/(authtoken)/([^/]*)(.*)$ $1$4 [E=HAS_auth:$3,L]
RequestHeader set AUTHTOKEN %{HAS_auth}e env=HAS_auth
SetHandler perl-script
PerlAccessHandler AuthHandler
So a request of the form "/foo/boo/moo/authtoken/baaaaaa/bar" is rewritten as "/foo/boo/moo/bar" and a request header "AUTHTOKEN: baaaaaa" added to the request.
The URI is being rewritten, and the test env var is being set, but the access handler (mod_perl) does not see the AUTHTOKEN header, or even ENV{HAS_auth} although the rewrite is working (I logged it).
Is it possible to actually to rewrite and set headers before the authentication(access) handler, and if so, how?

Rewrite authenticated Apache2.2 user for mod_proxy_ajp

I have a Tomcat connected via mod_proxy_ajp to an Apache2.2 instance. Apache does the authentication via mod_auth_kerb, and Tomcat uses request.getRemoteUser() to get the authenticated user.
This basically works, but I want to rewrite the user. However, none of the headers I set affect what is returned by request.getRemoteUser(), I only see them as additional headers, what do I have to do?
# Rewrite Magic: change REMOTE_USER to something Alfresco expects
RewriteEngine On
RewriteMap domain_map txt:/etc/apache2/rewrite-map.txt
# Grab the REMOTE_USER apache environment variable for HTTP forwarding (requires sub-request!)
RewriteCond %{LA-U:REMOTE_USER} (.*)#(.*)
# change the format and replace the domain, e.g.:
# user#some.domain ==> other.domain_user
RewriteRule . - [E=RU:${domain_map:%2|%2}_%1]
# copy processed user to HTTP headers
RequestHeader set REMOTE_USER %{RU}e
RequestHeader set HTTP_REMOTE_USER %{RU}e
RequestHeader set AJP_REMOTE_USER %{RU}e
RequestHeader set AJP_HTTP_REMOTE_USER %{RU}e
Thanks!
I suspect that the headers are not being set as you expect them to be set, and they are getting to Tomcat empty.
I have experienced some puzzling processing order issues that caused RequestHeader to ignore the environment variables set by a RewriteRule. Take a look at https://stackoverflow.com/a/9303018/239408 in case it helps
It seems the getRemoteUser() value can not be overwritten by Apache header directives, as the AJP protocol handler gets the username from some internal Apache structure. I worked around this by sending the username via http header and modifying the Java code to use that instead of using getRemoteUser().