Search code examples
web-servicestomcatcxfweb.xmlweb-inf

In which XML do I insert the RemoteAddrValve filter?


I would like to restrict one of my web services running under Tomcat 7. That is, I have one instance of Tomcat 7 hosting several web services. Some of these web services need not be restricted to a specific IP-address, so this restriction must be per-app.

Initial search on the subject suggests that it is possible to do so via a Remote Address Filter by adding something like:

<Context>
  <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="10\.180\.156\.159"/>
  <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"/>
</Context>

in "some" XML file that is part of the deployed WAR file.

My problem is that "some XML file" is very confusingly named. My understanding is that it is supposed to be the context XML but the context XML can be named anything... (it looks like the <param-name>contextConfigLocation</param-name> in <context-param> in web.xml that determines the name)

So, in the various sources providing the tips to implement this restriction, the references were to:

My context XML is named beans.xml and is located in the WEB-INF/classes subfolder...

Can someone please clarify this issue?

I am going to experiment now with my own guess, but an authoritative answer would be nice.


Solution

  • If you want to include the Valve for just one application, you would do this in a <Context/> block. As you have discovered, there are a few different places where you can configure the Context. Explanations of them below.

    META-INF/context.xml (my WAR has no META-INF subfolder, only WEB-INF)

    This is the only place where you can configure the context from your application. If you want to do this, simply create a META-INF folder in the root of your project (same location as WEB-INF directory). Inside META-INF, create a context.xml file and put your application specific configuration in there.

    When your application is deployed to Tomcat, this context file will (if Tomcat is configured to do so, see copyXML), copy the file into $CATALINA_BASE/conf/Catalina/localhost/<app-name>.xml and add include it in the configuration.

    conf\Catalina\localhost\manager.xml (looks tomcat-wide, not per-app)

    The actual format of this should be $CATALINA_BASE/conf/[enginename]/[hostname]/[appname].xml where [enginename] defaults to 'Catalina' and [hostname] defaults to 'localhost'. Thus for the "manager" application, the path you listed would be correct. If your application is called "myapp" then you'd use conf/Catalina/localhost/myapp.xml or for the ROOT app, you'd use conf/Catalina/localhost/ROOT.xml.

    This is the second location where you can put application specific Context configuration, and would be the one that I would recommend.

    There are two other places where you can put Context configuration, one is conf/context.xml and the other is conf/server.xml. Do not use conf/context.xml in this case because it would apply server-wide (i.e. across all of your apps). The conf/server.xml is possible to use, but I would suggest against it. Use of conf/server.xml for configuration like this is discouraged mainly because it's inflexible and requires a complete server restart when you make changes.

    In reference to...

    WEB-INF/web.xml (I do have that file, but it is the file that points to the context XML, not the context XML itself)

    This cannot be used for Context configuration, but you can use it to configure Servlet Filters and Tomcat ships with a RemoteAddressFilter, which does the same thing as the RemoteAddressValve.

    It's generally recommended to use a Filter, when available, versus a Valve.

    My context XML is named beans.xml and is located in the WEB-INF/classes subfolder...

    You cannot use a custom name or location for your Context configuration. It needs to match one of the names and locations specified by Tomcat. For more details on this, see here.