Showing posts with label RequestHeader. Show all posts
Showing posts with label RequestHeader. Show all posts

Monday, 24 February 2020

Apache: How to conditionally inject Authorization header

 In one of the cases I was helping with, I ran into a requirement that needed to have a webhook be sent from Jira to Jenkins to trigger a build based on certain condition.
You can trigger a webhook from Jira based on a Jira search query or on a certain action, eg: upon creation of an issue in a project for example.

The problem is that Jira doesn't support using userinfo fields in the URL, which is actually deprecated and should be used as per the RFC https://tools.ietf.org/html/rfc3986, and thus, Jira would have a way to send authentication information out of the box to Jenkins to trigger a build.

To solve this, I proposed to run Jenkins behind an Apache reverse proxy and use a virtual host definition similar to the below:

<VirtualHost *:80>
     ServerName feanor
     DocumentRoot /var/www/html/

     SetEnvIf Remote_Addr "10.0.0.12" buildtriggerjira
     RequestHeader set Authorization "Basic c2hlcmlmOnNoZXJpZg=="   env=buildtriggerjira

     ProxyPreserveHost on
     ProxyVia on
     ProxyPass "/jenkins" "http://feanor:8080/jenkins"
     ProxyPassReverse "/jenkins" "http://feanor:8080/jenkins"
</VirtualHost>

The above configuration will inject an Authorization header in the incoming request on condition that the remote address is the IP address of the Jira server.
This works by setting an Apache environment variable to a certain value in the SetEnvIf condition and then setting the Authorization header if the variable has that value set.

More checks can be made to harden the condition by checking more request fields like the user-agent string or other headers set by the Jira http client sending the webhook request.

Tuesday, 19 March 2019

Setting RequestHeader in Apache

Apache can be used to inject a Request Header in the incoming request that can be either consumed by Apache or forwarded further to another underlying service, in this case Apache works essentially as a reverse proxy.

In a test setup where Apache works as a reverse proxy in front of tomcat, the below Apache configuration is used to implement the reverse proxy functionality and add a Request Header:

<VirtualHost *>
   <Location "/sherif">
      ProxyPass http://127.0.0.1:8080/sherif
      ProxyPassReverse http://127.0.0.1:8080/sherif
      RequestHeader set myh "valueofarequestheader"
   </Location>
</VirtualHost>

In this setup, tomcat is using default port 8080, it has a defined context path for a dummy application defined in tomcat under its context.xml:

<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <Manager pathname="/sherif" />
</Context>


Under tomcat webapps, we have folder created as sherif and has a simple index.html file to support the test:
[root@localhost conf]# ls -lt ../webapps/sherif/
total 4
-rw-r--r-- 1 root root 14 Mar 19 16:27 index.html
[root@localhost conf]#

To verify the header being added, we configure tomcat to log the head myh.
This is done on tomcat server.xml accesslog value as below:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b %{myh}i" />

Once a request is sent to http://localhost/sherif, tomcat logs the below log showing the request header being added by Apache and reaching tomcat:

127.0.0.1 - - [19/Mar/2019:16:46:47 -0400] "GET /sherif/ HTTP/1.1" 200 17 valueofarequestheader

This configuration is useful in passing headers to backend services in case those are not already sent by the source user agent.