Proteger centralmente todas as aplicações web do tomcat usando autenticação BASIC

Eu tenho um servidor Tomcat 6 contendo três webapps: um personalizado como ROOT, Jenkins e Nexus.

Eu gostaria de proteger todos os três centralmente (server.xml?) Usando a autenticação BASIC.

Como posso conseguir isso sem modificar ou configurar os próprios aplicativos web?

Primeiro eu tentei (sem sucesso) include a válvula BasicAuthenticator em conf / context.xml . Isso não parece ter nenhum efeito.

Por fim, consegui que ele funcionasse (protegendo todos os aplicativos da Web) adicionando esse trecho ao conf / web.xml :

  Basic Authentication  /* GET POST   myrole    BASIC   My role myrole  

Duas maneiras vêm à mente:

  1. Você pode modificar conf / context.xml, que é incluído por todas as aplicações web, e inserir as diretivas de autenticação lá. A desvantagem é que você não pode excluir um webapp da autenticação, até onde eu saiba, e todos os webapps compartilharão os mesmos requisitos de function (embora pareça o que você precisa)
  2. Você pode implementar a segurança via apache ou algum outro servidor na frente do Tomcat. Isso faz sentido especialmente se você já tiver um.

Isso pode ser feito, mas você precisará trabalhar nisso.

Para o Tomcat, basicamente o que você quer é uma válvula de Tomcat . É como um Filtro de Servlet, mas é específico do Tomcat.

Você pode colocar uma Válvula na input HOST da configuração do seu servidor, então todos os aplicativos dentro desse Host precisarão passar por essa Válvula. E que a Valve é o que você precisa para lidar com sua autenticação BASIC.

O Tomcat já possui uma Válvula de Autenticação BASIC, mas foi projetada para funcionar com o aplicativo da web. Você provavelmente pode pegar a fonte para isso e hackeá-la para funcionar no nível do Host, em vez de no nível do Web App, protegendo, assim, todos os seus aplicativos sem configurá-los individualmente.

Agora, se você fosse um pouco mais aberto, eu sugeriria o Single Sign On do Tomcat e, em seguida, aumentaria cada um dos aplicativos da Web para usar o BASIC em seu web.xml seguindo as especificações do Servlet. É uma mudança basicamente trivial para os aplicativos individuais web.xml, mas também resolve o problema para você. Mas você disse que não queria modificar os aplicativos da Web, então você está preso usando o material específico do Tomcat e “fazendo a mão” por conta própria.

Isso é possível, mas o AFAIK não é possível sem (alguns) códigos. Aqui está uma solução que não toca nas aplicações web implementadas de qualquer forma, mas que também não lhe dá nenhuma autorização, apenas autenticação.

O Tomcat 7 (e o 6?) Têm um recurso bacana para executar a autenticação, mesmo que não haja resources protegidos no aplicativo da Web, chamado preemtiveAuthentication :

    

Pop que no seu contexto, onde quer que seja (talvez você precise criar $CATALINA_BASE/conf/Catalina/localhost/mywebapp.xml para proteger mywebapp.war).

Isso fará com que qualquer solicitação recebida com qualquer coisa no header Autorização acione a autorização. Qualquer solicitação sem o header de autorização ainda será enviada.

  • http://example.com:8080/mywebapp/ funcionará, enquanto GET /
  • http://user:password@example.com:8080/mywebapp/ não será (ou verificará um nome de usuário e senha)

O truque restante é, portanto, desarmar esse “recurso” toda vez, mesmo para usuários que não enviam nenhum header de autorização. Aqui é onde eu tive que voltar para uma válvula.

Aqui está o código para uma válvula que define um header de solicitação “Authorization” para “foo” se não estiver presente.

 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 o arquivo, dê a ele um bom pacote se você quiser e coloque-o no caminho de class compartilhado do Tomcat, e adicione change your mywebapp.xml da seguinte maneira (adicione a nova válvula antes do authenicator básico!):

     

E, voilá, o seu contexto não permitirá qualquer pedido , a menos que seja autenticado para o reino que você definiu.