Back-End

20 mai, 2013

Torne seus aplicativos do Tomcat mais seguros com SSL e Spring Security

Publicidade

Se você viu meu último artigo, saberá que eu listei 10 coisas que você pode fazer com o Spring Security. Entretanto, antes de começar a usar o Spring Security, uma das primeiras coisas que você realmente precisa fazer é se assegurar de que o seu aplicativo web utiliza o protocolo de transporte correto, que neste caso é o HTTPS – afinal de contas, não faz o menor sentido ter um servidor web seguro se você envia a senha de seu usuário em formato texto puro. Para configurar o SSL, há 3 passos básicos…

Criando uma key store

A primeira coisa que você precisa é de um chaveiro privado contendo um certificado válido, e a forma mais simples de gerar um é utilizando o utilitário keytool do Java localizado no seu diretório $JAVA_HOME/bin.

keytool -genkey -alias MyKeyAlias -keyalg RSA -keystore /Users/Roger/tmp/roger.keystore

No exemplo acima,

  • -alias é o identificador exclusivo da sua chave.
  • -keyalg é o algoritmo usado para gerar a chave. A maior parte dos exemplos que você encontrar na web irão citar o “RSA”, mas você também pode utilizar “DSA” ou “DES”.
  • -keystore é um parâmetro opcional que especifica a localização do arquivo da key store. Se esse parâmetro for omitido, então a localização padrão é o seu diretório $HOME.

RSA significa Ron Rivest (também criador do algoritmo RC4), Adir Shamir e Leonard Adleman

DSA significa Digital Signature Algorithm

DES significa Data Encryption Standard

Para mais informações sobre o keytool e seus parâmetros, dê uma olhada neste artigo do Informit, por Jon Svede.

Quando executar esse programa, algumas perguntas serão feitas para você:

Roger$ keytool -genkey -alias MyKeyAlias -keyalg RSA -keystore /Users/Roger/tmp/roger.keystore
Enter keystore password: 
Re-enter new password:
What is your first and last name?
  [Unknown]:  localhost
What is the name of your organizational unit?
  [Unknown]:  MyDepartmentName
What is the name of your organization?
  [Unknown]:  MyCompanyName
What is the name of your City or Locality?
  [Unknown]:  Stafford
What is the name of your State or Province?
  [Unknown]:  NA
What is the two-letter country code for this unit?
  [Unknown]:  UK
Is CN=localhost, OU=MyDepartmentName, O=MyCompanyName, L=Stafford, ST=UK, C=UK correct?
  [no]:  Y

Enter key password for 
     (RETURN if same as keystore password):

 

A maior parte dos campos é autoexplicativa; contudo, para os valores do primeiro e segundo nome, eu geralmente utilizo o nome da máquina – neste caso, localhost.

Atualizando a configuração do Tomcat

O segundo passo para melhorar a segurança do aplicativo é se certificar de que seu Tomcat possui um conector SSL. Para fazer isso, você precisa encontrar o arquivo de configuração server.xml do Tomcat, que normalmente se encontra no diretório “conf”. Uma vez que tiver feito isso e caso esteja utilizando o Tomcat, então será uma questão de retirar o comentário:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />

 

e fazer com que ele se pareça com isto:

<Connector SSLEnabled="true" keystoreFile="/Users/Roger/tmp/roger.keystore" keystorePass="password" port="8443" scheme="https" secure="true" sslProtocol="TLS"/>

Note que a senha “password” está em texto puro, o que é muito inseguro. Há formas de resolver isso, mas estas estão fora do escopo deste artigo.

Se você estiver utilizando o tcServer do Spring, vai perceber que ele já possui um conector SSL que está configurado como algo deste tipo:

<Connector SSLEnabled="true" acceptCount="100" connectionTimeout="20000" executor="tomcatThreadPool" keyAlias="tcserver" keystoreFile="${catalina.base}

…que em todo caso é apenas uma questão de editar os vários campos incluindo keyAlias, keystoreFile e keystorePass.

Configuração do aplicativo

Se você iniciar o Tomcat e executar o seu aplicativo web, irá perceber que ele está acessível utilizando HTTPS. Por exemplo, digitar https://localhost:8443/meu-aplicativo irá funcionar, mas http://localhost:8080/meu-aplicativo também. Isso significa que você terá que fazer alguns truques no seu aplicativo para ter certeza de que ele irá responder apenas por HTTPS e há duas formas de fazer isso.

Se não estiver utilizando o Spring Security, então pode simplesmente adicionar o seguinte trecho de código ao seu web.xml antes da última tag de web-app:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>my-secure-app</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

Se estiver utilizando o Spring Security, então há mais alguns passos para fazer isso. Parte da configuração do Spring Security é adicionar o trecho seguinte ao arquivo web.xml. Primeiro, você precisa acrescentar um arquivo de contexto de aplicativo Spring Security ao parâmetro contextConfigLocation context-param:

<context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/root-context.xml
           /WEB-INF/spring/appServlet/application-security.xml           
          </param-value>
     </context-param>

Em seguida, é preciso adicionar o filter e o filter-mapping do Spring Security:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

Por último, é necessário criar (ou editar) o seu application-security.xml como exibido no exemplo bem minimalista abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">

       <http auto-config='true' >
          <intercept-url pattern="/**" requires-channel="https" />    
       </http>

       <authentication-manager>
       </authentication-manager>

</beans:beans>

No exemplo acima, o elemento intercept-url foi configurado para interceptar todas as URLs e forçá-las a utilizar o canal https.

Os detalhes de configuração acima talvez passem a impressão de que é mais rápido utilizar a mudança simples na configuração do web.xml, mas se você já estiver utilizando o Spring Security, então é apenas uma questão de acrescentar os atributos requires-channel à sua configuração existente.

Um aplicativo de exemplo chamado tomcat-ssl, demonstrando o explicado acima está disponível em https://github.com/roghughe/captaindebug.

***

Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://www.captaindebug.com/2012/12/securing-your-tomcat-app-with-ssl-and.html#.UZVXJEBDu-R