Configure Apache for Angular and Tomcat on the same host - apache

I am trying to serve my application on a Centos 7 host, where I have deployed an Angular app for the frontend and Java Spring Boot app for the backend.
My versions are Apache 2.4.6, Tomcat 9 and Angular 7.
Let's say my domain is example.com. I want the user to write the following on the browser to access the Angular app routes, i.e. the frontend:
example.com/**
Also I would like to be able to write the following on the browser to access the Java app routes, i.e. the backend:
example.com/api/**
I tried to do it using Apache's mod_proxy, after reading this post: https://stackoverflow.com/a/33095758/350061. However, I only managed to serve Angular through example.com, while my API is only served on its original endpoint, that is example.com:8080/my-api and not through example.com/api.
These are my Apache settings:
/etc/httpd/conf.d/example.conf
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
DocumentRoot "/var/www/my-ng-app/dist/my-ng-app"
RewriteRule ^/api/(.*) http://localhost:8080/$1 [P,L,QSA]
ProxyPassReverse /api/ http://localhost:8080/
</VirtualHost>
/var/www/my-ng-app/.htaccess
RewriteEngine On
RewriteRule ^api/(.*) http://localhost:8080/my-api/$1 [P,L,QSA]
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
I have configured .htaccess to be read from that folder and verified that it is actually read. Also even if I remove the last part of .htaccess that redirects non-existing resources to index.html, the api does not get served from example.com/api, as I wish. It only gets served from example.com:8080/my-api
Any ideas on how to configure it?

After a long time of googling and trial and error, my solution consists of these changes:
I edited Tomcat's server.xml connector to serve requests through localhost. This made possible for rewrite settings to access my Java app through localhost:8080, but made impossible for me to access remotely my Java app through example.com:8080, which is fine.
I configured SELinux to allow Apache (httpd) to initiate outbound connections, in my case connections to localhost
I applied some fixes on my original VirtualHost and .htaccess configuration
More specifically:
sudo nano /opt/tomcat/latest/conf/server.xml
Find the connector for port 8080 and add address attribute as such:
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"
redirectPort="8443" />
/usr/sbin/setsebool -P httpd_can_network_connect 1
The -P persist the setting for future reboots
/etc/httpd/conf.d/example.conf
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
DocumentRoot "/var/www/my-ng-app/dist/my-ng-app"
RewriteRule ^/api/(.*) http://localhost:8080/my-api/$1 [P,L,QSA]
ProxyPassReverse /api/ http://localhost:8080/my-api/
</VirtualHost>
/var/www/my-ng-app/.htaccess
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
After these changes just restart Tomcat and Apache and you will be able to access your API through example.com/api

Related

mod_rewrite - Port 80 does not change to 443 when HTTP is explicitly requested

I have an app deployed to Elastic Beanstalk whose Tomcat container uses Google OpenID Connect for authentication. I want to redirect all http requests to https, for which I have the following mod_rewrite configuration in a file in .ebextensions -
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Google OAuth2 credentials console has https://example.com/j_security_check as an authorized redirect URL. The configuration works fine when either example.com or https://example.com is requested, whereupon the app is redirected to the mentioned authorized URL.
However, when http is explicitly requested - http://example.com - the app is being redirected to https but port 80 is still being used. The authorized redirect URL then becomes https://example.com:80/j_security_check and I get Error: redirect_uri_mismatch.
How can I redirect explicit http requests to https with the port changed to 443? The main goal is to match the mentioned authorized redirect URL. If possible, I'd like to implement this with the .ebextensions configuration file or a similar solution.
Can you something like this. If it got worked I will give you the explanation.
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
The problem was not with the rewrite rule. The file had to be placed in a specific path within .ebextensions for it to work in Tomcat 8. The configuration files had to be setup differently too. Most examples provided were not for Tomcat so I ended up putting them in the wrong location.
What worked -
In /.ebextensions/httpd/conf.d/myconf.conf, place -
LoadModule rewrite_module modules/mod_rewrite.so
and in /.ebextensions/httpd/conf.d/elasticbeanstalk/00_application.conf, place -
<VirtualHost *:80>
<Proxy *:80>
Order Allow,Deny
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
Take note of the use of .conf files instead of .config. This is important!
Also, the redirection that I was getting was not genuine. I was not paying close attention, because when I requested example.com, the browser cache was serving me https://example.com. It was not actually redirecting an http request to https.

Apache Web Server (httpd) - Files over proxy pass

I have an Apache httpd setup with VirtualHost
I am doing some ProxyPass and ProxyPassReverse so I can redirect calls to a local server.
What I want is to have the ability to mock some endpoints with files on the apache server if they exist.
So for example I have the endpoint
http://localhost:8080/myapp/myendpoint
and now when I run
http://localhost/myapp/myendpoint
apache with my VirtualHost setup redirects the calls to my local server
Now lets say I put a file in {apache main dir}/htdocs/myapp/ called myendpoint .
If I remove the Location tag with ProxyPass in VirtualHost calling
http://localhost/myapp/myendpoint returns the results of the file in htdocs. But if I leave the above Location tag in the configuration it ignores the file and goes to the server.
How can I configure Apache Web Server to give priority to the file before doing the proxypass?
Instead of
ProxyPass /localhost/myapp/ http://localhost:8080/localhost/myapp/
ProxyPassReverse /localhost/myapp/ http://localhost:8080/localhost/myapp/
You can try with
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /localhost/myapp/ http://localhost:8080%{REQUEST_URI} [P]
ProxyPassReverse /localhost/myapp/ http://localhost:8080/localhost/myapp/
(http://httpd.apache.org/docs/current/rewrite/flags.html#flag_p, notice the Performance warning)

How to configure Apache virtual hosts based on referer?

We have a tomcat web server running in port 8080 and Apache server running in port 80 in windows environment. Our objective is to configure, Apache server as proxy server to hide the tomcat web server address to the users.When i tried to use mod_rewrite based on HTTPREFERER rule it's working fine but user can able to see the redirected URL in the browsers network tab.
RewriteEngine on
RewriteMap deflector "txt:C:/gsasetup/gsaproxy01/Apache24/conf/deflector.map"
RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "${deflector:%{HTTP_REFERER}}" "=-"
RewriteRule "^" "%{HTTP_REFERER}" [R,L]
RequestHeader set Authorization "Basic dXNlcjpwYXNzd29yZA==" env=DOAUTH
RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "${deflector:%{HTTP_REFERER}|NOT-FOUND}" "!=NOT-FOUND"
RewriteRule "^" "${deflector:%{HTTP_REFERER}}" [R,L]
Similarly, when i tried using virtual hosts configuration it's internally redirecting the requests to tomcat web server running in port 8080.
ServerName localhost
ServerAlias *.localhost
ProxyRequests off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
But here what i want is the combination of both. Means proxy should happen only for specific referrer. Otherwise i want to send user unauthorized response.
Is this kind of configuration possible?

Apache Rewrite Rules for CentOS Grails Application with Tomcat

I am using Apache and Tomcat on a CentOS box and I want to do the following rewrites:
I want to handle abc.com to redirect to www.abc.com when a request is made.
I want to load my resources with Apache instead of Tomcat
This is my conf file. It is located in /etc/httpd/conf.d/tomcat.conf
#
# This configuration file enables the default "Welcome"
# page if there is no default index page present for
# the root URL. To disable the Welcome page, comment
# out all the lines below.
#
RewriteEngine on
RewriteRule ^/images/(.*) /images/$1
RewriteRule ^/css/(.*) /css/$1
RewriteRule ^/js/(.*) /js/$1
RewriteCond %{HTTP_HOST} ^abc\.com
RewriteRule ^(.*)$ http://www.abc.com$1 [R=301,L]
NameVirtualHost *:80
<VirtualHost *:80>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / ajp://127.0.0.1:8009/
ProxyPassReverse / ajp://127.0.0.1:8009/
ProxyPassReverseCookiePath / /
</VirtualHost>
My AJP proxy rewrite is working, I just need to do the following rewrites above.
apache redirect from non www to www
To load your resources with apache instead of tomcat, you can:
use apache mod_cache module, so you can decrease your tomcat load dramatically by caching your resources (css, js, images)
add servlet filters in your web application to set http cache headers in order to enable caching

Apache Virtualhost Directory conditional redirect

I just created a website with two environments as virtualservers - testing and production. As production server is open to everyone but I allowed only my IP to access testing environment:
<VirtualHost *:80>
DocumentRoot /home/xxx/www
ServerName testing.xxx.com
<Directory /home/xxx/www>
Order deny, allow
Deny from all
Allow from xxx.xxx.xxx.xxx
</Directory>
</VirtualHost>
The problem is that google has already indexed some of my testing environment pages and they are available in google results. I would like any IP but mine to be redirected to production server (xxx.com) while accessing testing.xxx.com. I would rather do it with apache.conf than .htaccess(because of git repositories conflicts). Is it possible to add a conditional redirect to apache config?
You can use mod_rewrite features in your httpd.conf Apache config file:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REMOTE_HOST} !^123\.456\.788 [OR] # exclude your first IP
RewriteCond %{REMOTE_HOST} !^123\.456\.789 # exclude your second IP
RewriteRule ^(.*)$ http://production-env.com/$1 [R=301,L] # redirection to production site
</IfModule>
Or you can put these declarations into <Directory> section of your vhosts config file.
Generally you can take advantage of mod_rewrite module to manage URL routing policies for your web server. Before using it make sure that this module is installed and activated in your Apache.