Centrally secure all tomcat web applications using BASIC authentication

I have a Tomcat 6 server containing three webapps: custom like ROOT, Jenkins and Nexus.

I would like to protect all three centrally (server.xml?) Using BASIC authentication.

How can I achieve this without changing or customizing the webapps themselves?

+6
java tomcat tomcat6 basic-authentication
source share
4 answers

First, I tried (without success) to enable the BasicAuthenticator valve in conf / context.xml. This showed no effect.

Finally, I got it to work (provided all the web applications) by adding this snippet to conf / web.xml :

<security-constraint> <web-resource-collection> <web-resource-name>Basic Authentication</web-resource-name> <!--Here wildcard entry defines authentication is needed for whole app --> <url-pattern>/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>myrole</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> </login-config> <security-role> <description>My role</description> <role-name>myrole</role-name> </security-role> 
+7
source share

Two ways come to mind:

  • You can change the conf / context.xml that is included in all webapps and insert authentication directives there. The disadvantage is that you cannot exclude one webapp from authentication, as far as I know, and all web applications will use the same role requirements (although this sounds the way you need it).
  • You can implement security through apache or some other web server running in front of Tomcat. That makes sense, especially if you already have one.
+4
source share

This can be done, but you will need to work on it.

For Tomcat, you mostly need Tomcat Valve . This is similar to a servlet filter, but it is specific to Tomcat.

You can put Valve in the HOST record of your server configuration, then all applications inside this host will have to go through this valve. And this Valve is what you need to handle your BASIC authentication.

Tomcat already has a BASIC Authentication Valve, but it is designed to work with a web application. You can probably grab the source and hack it to work at the host level, not at the web application level, thereby protecting all your applications without having to configure them separately.

Now, if you were a little more open, I would suggest Tomcat Single Sign On , and then increase each web application to use BASIC in its web.xml, following the Servlet specification. This is a fundamentally trivial change for individual web.xml applications, but it also solves the problem for you. But you said you didn’t want to change web applications, so you’re stuck using Tomcat specific things, and you manually create it yourself.

+2
source share

This is possible, but AFAIK is not possible without (some) code. Here is a solution that does not affect deployed webapps in any way, but which also does not give you any fine-grained authorization, only authentication.

Tomcat 7 (and 6?) Has a great feature for authentication, although the web application does not have secure resources called preemtiveAuthentication

 <Context preemptiveAuthentication="true"> <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" /> </Context> 

Pop, which is in your context, wherever it may be (perhaps you need to create $CATALINA_BASE/conf/Catalina/localhost/mywebapp.xml to protect mywebapp.war).

This will make any incoming request with anything in the authorization header to initiate authorization. Any request without an authorization header will still pass.

  • http://example.com:8080/mywebapp/ will work, and GET /
  • http://user: password@example.com :8080/mywebapp/ will not (or it will check the username and password)

Thus, the remaining trick should disable the "every time" function, even for users who do not send any authorization header. That's where I had to go back to the valve.

Here is the code for the valve that sets the "Authorization" request header to "foo" if it is missing.

 import javax.servlet.ServletException; import java.io.IOException; import org.apache.catalina.valves.ValveBase; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; public class ConditionallyAddFakeAuthorizationHeader extends ValveBase { public void invoke(Request request, Response response) throws IOException, ServletException { if (request.getCoyoteRequest().getMimeHeaders().getValue("authorization") == null) { request.getCoyoteRequest().getMimeHeaders().addValue("authorization").setString("foo"); } getNext().invoke(request, response); } } 

Compile the file, give it a nice package if you want, and put it in the general path of the Tomcat class and add the change to mywebapp.xml as follows (add a new valve in front of the base authenticator!):

 <Context preemptiveAuthentication="true"> <Valve className="ConditionallyAddFakeAuthorizationHeader"/> <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" /> </Context> 

And in your context, no request will be allowed through unless it is authenticated with respect to the area that you defined.

+1
source share

All Articles