O emprego de mecanismos poderosos de segurança em uma aplicação web é, na grande maioria dos casos, um requisito que não pode ser ignorado. A exploração de uma falha no sistema pode resultar em prejuízos financeiros incalculáveis para uma organização e causar demissões em massa na equipe do projeto.
Nestes cenários em que se deseja proteger os sistemas, é sempre recomendada a adoção de camadas de segurança implementadas pelas equipes envolvidas no projeto. Em um ambiente corporativo, estas camadas costumam estar divididas em quatro, sendo a primeira relacionada diretamente à infraestrutura, compreendendo o acesso dos usuários a servidores, seja ele físico ou lógico. Na camada seguinte, há o envolvimento da estrutura de rede, na qual contamos com firewalls, VPNs e DMZs para limitar a visibilidade de uma rede ou IP. Além destes equipamentos, normalmente utiliza-se um sistema de detecção de ataques para evitar problemas com DoS (Denial of Service) ou algoritmos de força bruta. Subindo mais uma camada, temos a Máquina Virtual Java, que implementa uma série de controles de segurança baseados em permissões concedidas a tipos primitivos e classes da linguagem para evitar a exploração de uma brecha no código. A última camada – e talvez a mais importante de todas – trata do controle de segurança nas aplicações e está ligada, principalmente, aos mecanismos de autenticação e autorização.
Como uma resposta para a necessidade de haver uma boa solução para aplicações Java no que diz respeito à quarta camada, surgiram diversas opções de bibliotecas que tentam combater ataques e exploração de falhas no projeto, como acesso não autorizado a recursos, leitura de dados confidenciais de usuários e até mesmo uma invasão no sistema.
Neste artigo, veremos como utilizar os mecanismos de autenticação e autorização do Spring Security em uma aplicação web que simula o funcionamento de uma locadora. O sistema rodará com JSF 2.2, CDI 1.1 para injeção de dependências e JPA 2.1 para acesso a uma base de dados no PostgreSQL. Além destes três frameworks, o Maven será configurado para gerenciamento das dependências e do build, e nosso servidor de aplicação será o WildFly 8.0.
O JavaServer Faces 2.2
O JavaServer Faces é um framework MVC orientado a eventos lançado em 2004 para a construção da camada de visão através do uso de componentes. Desde o seu primeiro release, a biblioteca vem ganhando cada vez mais adeptos, por se tratar de um produto oficial Java EE e apresentar um grande envolvimento de usuários na especificação da JSR.
Na versão 2, o JSF trouxe algumas novidades importantes, como o fim da necessidade de declarar os Managed Beans e as regras de navegação no faces-config.xml, um novo escopo entre requisição e sessão chamado ViewScope, suporte nativo a Ajax, possibilidade de usar bookmarking (ver BOX 1), entre outros.
Como qualquer outro produto de mercado, entretanto, o JavaServer Faces continua passando por aprimoramentos, e a versão 2.2, lançada em abril de 2013, não poderia deixar de lado novos recursos fundamentais. Entre eles, podemos citar:
• Adição de suporte ao escopo FlowScoped;
• Maior integração com o CDI;
• Melhoria no suporte a HTML5;
• Proteção contra ataques do tipo CSRF (Cross-Site Request Forgery).
BOX 1. Bookmarking
Refere-se à possibilidade de colocar uma página interna do sistema como um favorito do navegador para poder voltar a ela de forma direta posteriormente. Muito utilizado em sites de compras, de pesquisa, entre outros.
O Spring Security 3.2
O Spring Security foi lançado em 2003 com o propósito de incorporar recursos avançados de segurança à plataforma Java EE. Assim como os concorrentes, a biblioteca dispensa a realização de configurações no servidor de aplicação, facilitando o trabalho da equipe do projeto em uma possível migração de container.
Embora o framework faça parte do conjunto de projetos Spring, ele pode ser utilizado em sistemas Java com as mais diversas arquiteturas, independentemente de ter sido incorporada ou não a biblioteca com o core do Spring. Na versão 3.2, os principais recursos fornecidos pelo Spring Security são:
• Suporte extensível para autenticação e autorização;
• Proteção contra ataques de fixação de sessão, CSRF (Cross-Site Request Forgery) e clickjacking;
• Integração com a API de Servlets;
• Possibilidade de configuração da segurança utilizando apenas código Java, ou seja, sem o uso de arquivos XML.
Criando a aplicação
A partir de agora, criaremos um pequeno sistema de locadora para demonstrar os principais recursos do Spring Security. A injeção de dependências será feita pelo CDI e o papel de controller caberá ao JSF 2.2. O banco de dados com os usuários cadastrados para autenticação na aplicação será acessado através da JPA 2.1 e constarão dois perfis de acesso: administrador e operador. O perfil administrador terá permissão de realizar qualquer operação no sistema, enquanto o usuário operador não poderá cadastrar filmes.
O ambiente requerido para implementar o sistema envolverá os softwares listados a seguir, que precisam estar instalados na máquina em que a implementação dos exemplos deste artigo será feita (se necessário, confira a seção Links no final do artigo para saber onde baixá-los):
• Servidor de aplicação WildFly 8.0.0. Se quiser saber mais detalhes sobre como configurá-lo, consulte a Java Magazine 128;
• Eclipse Kepler para desenvolvedores Java EE;
• Java Development Kit versão 1.7 configurada no Eclipse;
• SGBD PostgreSQL 9.3.
Agora que temos todos os softwares configurados na máquina, vamos criar o projeto Maven. Para isso, na view Project Explorer do Eclipse, clique com o botão direito, selecione New e clique em Other.
Na tela que surge, selecione Maven e depois clique em Maven Project. Marque a opção Create a simple Project (skip archetype selection) e clique em Next. Neste passo, informe no campo Group Id o valor “br.com.javamagazine”, no Artifact Id o valor “locadora”, no Packaging o valor “war” e no Name o valor “locadora”. Em seguida, clique em Finish.
Logo após, vamos configurar nosso projeto para utilizar o JSF 2.2 e informar alguns parâmetros adicionais para a aplicação rodar corretamente. Assim, clique com o botão direito em cima da raiz do projeto, e depois na opção Properties. Na tela que surge, clique em Project Facets. No item Dynamic Web Module, selecione a versão 3.1 para trabalharmos com a versão mais recente da API de Servlets. No item Java, selecione a opção 1.7 e marque o item abaixo, JavaServer Faces, selecionando posteriormente a versão 2.2 do framework. Mais abaixo, surgirá a mensagem Further configuration available informando que é preciso confirmar alguns parâmetros do JSF. Clique nela e informe as seguintes configurações para o funcionamento da aplicação: em JSF Implementation Library, deixe marcado Disable Library Configuration; no campo URL Mapping Patterns, clique em cima da opção existente (/faces/*) e depois no botão Remove. Feito isso, clique no botão Add e no popup que aparece, informe “*.xhtml”. Então, clique em OK na primeira tela, em OK na segunda e novamente em OK na terceira para confirmar as mudanças.
Nosso próximo passo será informar o uso da versão 3.1 da API de Servlets no web.xml e configurar a página inicial do sistema. Para realizar esta alteração, abra o arquivo mencionado, que se encontra na pasta src/main/webapp/WEB-INF, e informe o código presente na Listagem 1.
Listagem 1. Código do arquivo web.xml.
01 <?xml version="1.0" encoding="UTF-8"?>
02 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
03 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
04 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
05
06 <display-name>locadora</display-name>
07
08 <welcome-file-list>
09 <welcome-file>inicio.xhtml</welcome-file>
10 </welcome-file-list>
11
12 <servlet>
13 <servlet-name>Faces Servlet</servlet-name>
14 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
15 <load-on-startup>1</load-on-startup>
16 </servlet>
17 <servlet-mapping>
18 <servlet-name>Faces Servlet</servlet-name>
19 <url-pattern>*.xhtml</url-pattern>
20 </servlet-mapping>
21 </web-app>
Modificando o pom.xml
Como iremos utilizar várias bibliotecas diferentes não fornecidas diretamente pelo JDK no projeto, precisamos configurá-las no pom.xml. Deste modo, clique duas vezes sobre ele e selecione a aba pom.xml para editar o código fonte, que deve ficar semelhante ao da Listagem 2.
Listagem 2. Código do arquivo pom.xml.
01 <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
02 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
03 <modelVersion>4.0.0</modelVersion>
04
05 <groupId>br.com.javamagazine</groupId>
06 <artifactId>locadora</artifactId>
07 <version>0.0.1-SNAPSHOT</version>
08 <packaging>war</packaging>
09
10 <name>locadora</name>
11
12 <build>
13 <plugins>
14 <plugin>
15 <artifactId>maven-compiler-plugin</artifactId>
16 <version>2.0.2</version>
17 <configuration>
18 <source>1.7</source>
19 <target>1.7</target>
20 </configuration>
21 </plugin>
22 </plugins>
23 </build>
24
25 <dependencies>
26 <!-- Bibliotecas JavaEE 7 que já estão no Wildfly, incluindo o JSF 2.2 -->
27 <dependency>
28 <groupId>javax</groupId>
29 <artifactId>javaee-api</artifactId>
30 <version>7.0</version>
31 <scope>provided</scope>
32 </dependency>
33
34 <!-- Spring Security -->
35 <dependency>
36 <groupId>org.springframework.security</groupId>
37 <artifactId>spring-security-web</artifactId>
38 <version>3.2.3.RELEASE</version>
39 </dependency>
40 <dependency>
41 <groupId>org.springframework.security</groupId>
42 <artifactId>spring-security-config</artifactId>
43 &l ...