Com as exigências dos clientes e os requisitos ficando cada vez mais complexos, temos que de alguma forma centrar todas nossas forças em apenas resolver o problema do cliente e tentar abstrair ao máximo outras funcionalidades importantes mas não essenciais ao cliente, os requisitos não funcionais.

Neste artigo vamos tratar de um requisito não funcional: A Segurança. Para um cliente que solicita a construção de um software, é óbvio e evidente que a segurança é importante, ele não precisa dizer isso, pois é tão óbvio que você como profissional já deve saber desde o inicio. É como comprar um carro e dizer que você quer que seu carro tenha freios, isso é implícito.

Então o principal objetivo é não perder muito tempo desenvolvendo a segurança de uma aplicação, para isso recorremos a Frameworks que nos fornecem tal funcionalidade, o Spring Security. Há outros como o JAAS, jGuard (que funciona com o JAAS) e assim por diante, mas se você já utiliza o Spring, seria uma boa ideia aproveitá-lo para gerenciar a sua camada de segurança. A questão é, se você usa Spring apenas para injeção de dependência talvez não seja uma boa ideia, pois você tem uma ferramenta muito poderosa cheia de recursos e não está utilizando, é como comprar uma fábrica de automóveis apenas para ter um carro, totalmente desnecessário.

Instalando e Usando o Spring Security

Em nossos exemplos vamos utilizar o Maven para gerenciar nossas dependências. Alguns podem pensar: Para que tantos Frameworks ? Isso não torna nossa aplicação pesada e lenta ? A resposta é: A quantidade de Frameworks que utilizamos é para tentar abstrair ao máximo a tecnologia e focar nas regras de negócio, afinal o cliente não quer saber como você faz, apenas que você o faça. Uma aplicação bem gerenciada e com os frameworks e configurações necessárias raramente terá problemas frequentes de lentidão.

Após muita introdução e explicações do porque usar o Spring Security, vamos enfim utilizá-lo. Vamos partir do principio que você já utiliza o Spring Framework, assim apenas adicionaremos as 3 bibliotecas necessárias ao Spring Secutiry, são elas: spring-security-core.jar, spring-security-web.jar e spring-security-cofing.jar. Vamos adicioná-las no nosso pom.xml, assim como na listagem 1.

Listagem 1: Adicionando bibliotecas necessárias


<properties> 
		<spring.version>3.0.5.RELEASE</spring.version> 
	</properties> 
  
	<dependencies> 
  
		<!-- Spring 3 --> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-core</artifactId> 
			<version>${spring.version}</version> 
		</dependency> 
  
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-web</artifactId> 
			<version>${spring.version}</version> 
		</dependency> 
  
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-webmvc</artifactId> 
			<version>${spring.version}</version> 
		</dependency> 
  
		<!-- Spring Security --> 
		<dependency> 
			<groupId>org.springframework.security</groupId> 
			<artifactId>spring-security-core</artifactId> 
			<version>${spring.version}</version> 
		</dependency> 
  
		<dependency> 
			<groupId>org.springframework.security</groupId> 
			<artifactId>spring-security-web</artifactId> 
			<version>${spring.version}</version> 
		</dependency> 
  
		<dependency> 
			<groupId>org.springframework.security</groupId> 
			<artifactId>spring-security-config</artifactId> 
			<version>${spring.version}</version> 
		</dependency> 
  
	</dependencies> 
  
</project>

O Maven se encarregará de realizar o download e gerencia das bibliotecas necessárias, descritas no pom.xml.

Agora iremos criar um arquivo chamado spring-security.xml que ficará na mesma pasta do web.xml. Neste arquivo diremos o que cada usuário vai acessar com qual regra.

Listagem 2: Definindo o spring-security.xml


<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.0.3.xsd>"> 
  
	<http auto-config="true"> 
		<intercept-url pattern="/admin*" access="ADMIN_USER" /> 
	</http> 
  
	<authentication-manager> 
	  <authentication-provider> 
	    <user-service> 
		<user name="admin" password="123456" authorities="ADMIN_USER" /> 
	    </user-service> 
	  </authentication-provider> 
	</authentication-manager> 
  
</beans:beans>

No arquivo XML acima definimos um usuário chamado 'admin' com senha '123456' que faz parte de um grupo chamado “ADMIN_USER”. Poderíamos aqui fazer uma mixagem de regras de acordo com cada grupo. O objetivo aqui é definir regras para os grupos e não para os usuários, pois estes farão parte dos grupos, assim poderemos criar quantos usuários quisermos sem ter que ficar mudando regras de grupos.

O próximo é habilitar na nossa aplicação o filtro do Spring Security, assim ele poderá “capturar” todas as páginas e realizar uma filtragem própria para garantir o acesso restrito por usuário e senha, fazemos isso através do web.xml.

Listagem 3: Configurando Spring Security no web.xml


<!-- 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>

Ainda no web.xml você configura o XML que será carregado para configuração do spring, o applicationContext.xml, então é nessa mesma tag que você deverá definir o spring-security.xml, assim como na listagem 4.

Listagem 4: Definindo o spring-security.xml para ser carregado na aplicação [web.xml]


<!-- Configuracao do Spring -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring-security.xml, /WEB-INF/applicationContext.xml</param-value>
	</context-param>

Provavelmente você pode encontrar alguns problemas ao tentar inicializar o Spring Secutiry, então vamos tentar preveni-los antes que eles aconteçam e tragam uma enorme dor de cabeça.

  • Verifique se o trecho de código “${spring.version}” está de acordo com a sua versão do spring, pois esta também poder variar para “${org.springframework.version}”. De qualquer forma, agora você já sabe que há ainda uma outra possibilidade.
  • Para facilitar a visualização do Spring Security funcionando vamos apontar a configuração abaixa para levar ao usuário a uma tela de login bem simples apenas para você ver o sistema funcionando. Para isso deixar seu spring-security.xml como na listagem abaixo.

Listagem 5: Autenticação HTTP Básica - Login Simples


<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.0.3.xsd>"> 
  
	<http auto-config="true"> 
		<intercept-url pattern="/admin*" access="ADMIN_USER" /> 
		<http-basic />
	</http> 
  
	<authentication-manager> 
	  <authentication-provider> 
	    <user-service> 
		<user name="admin" password="123456" authorities="ADMIN_USER" /> 
	    </user-service> 
	  </authentication-provider> 
	</authentication-manager> 
  
</beans:beans>

A linha “<http-basic />” dispensa a criação de uma tela de login própria, assim poupará você o trabalho de criação desta tela. O problema é que com esta login você apenas poderá realizar o login, sem nenhuma opção para recuperação de senhas. Ideal para sistemas onde não terá possibilidade de recuperação de senhas através de uma opção simples como: “Esqueci minha senha”.

Caso você queira capturar usuários e regras (grupos) via database, você pode substituir o bloco de código 'authentication-manager' pelo mostrado na listagem 6.

Listagem 6: Configurando usuários e ROLES via database


<authentication-manager> 
	   <authentication-provider> 
		<jdbc-user-service data-source-ref="dataSource" 
  
		   users-by-username-query=" 
		      select username,password, enabled 
		      from users where username=?" 
  
		   authorities-by-username-query=" 
		      select u.username, ur.authority from users u, user_roles ur 
		      where u.user_id = ur.user_id and u.username =?  " 
  
		/> 
	   </authentication-provider> 
	</authentication-manager>

Esta foi uma introdução ao Spring Security como alternativa para criação de uma camada de segurança robusta e de simples gerenciamento, sem a necessidade de dias ou semanas trabalhando em um módulo próprio para aumentar a segurança do sistema.