I am trying to configure tomcat so that my application will be accessible via two different ports, say 8080 and 8980, but certain URLs will be accessible via only 8980.
The reason is that the web tier uses 8080 and I don't want certain URLs to be exposed to the outside world. I also don't want to configure web servers to restrict this, because of the coupling it creates between the app and the web tier.
I understand that I can configure two connectors and then programmatically block calls to the URLs based on the port, but:
I would rather not hard-code the port, as it may be changed in
the future in the server.xml
I want this same behaviour in various
applications in the organization, and don't want all developers to
need to implement this separately.
Is there a configuration where I can, perhaps, exclude certain URL patterns from a connector that is defined in server.xml?
Thanks in advance!
In tomcat, you can define multiple services with different connector ports and engine settings, but an application will only be served by one engine, so you'd have to deploy your application multiple times.
For use cases like yours, tomcat is too limited, but this functionality is usually deferred to a Reverse proxy, e.g. apache or nginx.
You could for example let your tomcat serve on port 8980, and configure an apache to reverse proxy all /app calls on port 8080, except the internals:
Listen 8080
<VirtualHost *:8080>
ProxyPass /app/internal !
ProxyPass /app http://localhost:8980/app
</VirtualHost>
See http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass
Related
Relatively new to jboss fuse. We have a requirement of running a single application on multiple ports. Is it practically possible? specify a range of port in config file.
I tried like cfg.port: 9000, 9001
but doesnt work
The best approach is to have the application's Camel routes that use those ports define them in their routes. The built-in Jetty listener is generally for shared web service endpoints using CXF and the management web console.
I am managing a server providing web administration pages and communicating with client apps.
I designed the web part which allows the public access through the 80 port.
However, I was told from my client that they want the server to allow only the access from their intra-net other than outside the company.
I thought it can be done if Tomcat has an ability to filter the access to web pages based on IP address.
However, I ended up in failing to find out a proper solution for that. I know Tomcat has already provided the filtering function according to a web project.
I came up with a way of getting around this problem and used it as follows:
I make two service tags in server.xml like
<Service name="Catalina">
<Connector port="80" ...>
<Service name="Catalina2">
<Connector port="8080" ...>
And make another clone for the additional service. Then, I block all the external accesses through 8080 port by the firewall set-up. This lives up to my client’s needs.
However, this is not a common way, I guess. Even, sometimes, the setting allows the external accesses which shouldn’t happen. On top of this, it’s not an efficient way from the maintaining point of view.
Anyhow, I don’t like it. It would be appreciated if someone told me the way.
Thanks for reading the question.
A first step to IP filtering would be to configure your firewall / router.
You can also implement easy IP filtering in Servlet containers by creating a javax.servlet.Filter.
You can map the filter using wildcards (*) to have all requests go through it and in the filter you can check the client's IP and block / deny serving the request based on your own rules.
Tomcat also comes with some built-in Filters. You might wanna take a look at them:
Apache Tomcat 8 Container Provided Filters
The built-in filters include Remote Address Filter, Remote Host Filter and Remote IP Filter (for proxies). These are mostly configurable with regular expressions and may be enough for your needs.
I have a Java webservice running on Tomcat in our internal environment. Let's say the wsdl is
http://actual:8080/app/temp?wsdl
To provide access to this webservice from outside the network, we created a proxy using Apache on another server and used ProxyPass to do something like
ProxyPass /app/temp http://actual:8080/app/temp
So externally when we access proxy/app/temp over http, it gets diverted to actual:8080/app/temp just fine. So no issues with that, and I can also access the wsdl.
But the WSDL has references to "actual" server for the "webservice location" on the port. This causes failure when an actual call is made to the webservice methods from a client.
Any ideas on how this can be fixed, please? Thanks.
Note: The client is generated using Metro. I found a way to force a different endpoint in the client using a code like below. But I am looking more for a pure proxy solution that we can do, instead of developers using our webservice having to touch their code.
((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://proxy/app/temp?wsdl");
You can use the ProxyPreserveHost directive. Quoting from the directive's section in the link:
When enabled, this option will pass the Host: line from the incoming
request to the proxied host, instead of the hostname specified in the
ProxyPass line
therefore you should have the following in your configuration file:
ProxyPreserveHost On
ProxyPass /app/temp http://actual:8080/app/temp
and then restart apache server.
using this option, you will not need to change anything in web service related code or setup.
I've had experience forwarding requests between separate webapps by updating each webapp's META-INF/context.xml to contain crossContext="true".
However, I have a situation now where I have webapps deployed within the same running tomcat but in entirely separate areas. To elaborate, in tomcat's server.xml:
app1 uses Service with name "app1Svc" with its own Connectors (to allow running on separate ports), so therefore its own Engine, Realm, and Host.
app2 has a similar setup, with a distince Service named "app2Svc" with its own connectors, etc.
If I run these webapps within the same host, I can dispatch requests between the two via their context.xml's crossContext="true" and obtaining the relevant servlet context to forward the request to (as per Tomcat not able to get ServletContext of another webapp).
However, is this possible to dispatch between two webapps that essentially have to run on separate ports (without putting httpd or somesuch in front of tomcat)?
Not in a native way, which is probably good.
You can access then by generating http requests from one to the other. For that purpose you need each of them expose some functionality over http (perhaps RESTfully). In order to make the requests you can use apache http components, or simply URL.openConnection(). You will just need to supply the URL (+port) of other apps to the application, so that they can make the invocations.
I have added this transport-guarantee tag in the web.xml meaning that certain pages can only be accessed by https. But however this has an issue with environment that has web server and load balancer.
Apparently it does not redirect to the application with ssl port.
Seens like a firewall restriction.
Any advise anyone?
Which container are you using? I believe some containers do allow you to specify the "front end" (i.e., web server, load balancer etc) SSL port in configuration.
I've done this for WebLogic, but I'm not sure if this requirement is explicitly speced out in the Java EE specs, or if all containers support it.