Artigo do tipo Tutorial
Recursos especiais neste artigo:
Artigo no estilo Curso Online
Conhecendo o Apache Shiro – Parte 2
Esta é a segunda parte do artigo que apresenta o Apache Shiro. No artigo anterior, foram mostrados os conceitos que envolvem sua utilização e alguns exemplos de código, mas nada muito prático. Neste artigo, desenvolveremos uma aplicação de exemplo utilizando o Apache Shiro como nosso framework de segurança.

Em que situação o tema é útil
Este tema é útil àqueles que desejam uma forma fácil e intuitiva de implementar segurança em sistemas desenvolvidos em qualquer plataforma Java. Esses possivelmente já esbarraram nas dificuldades de se utilizar alguns frameworks de segurança ou na falta deles em todos os tipos de ambiente. O Apache Shiro surge como uma boa opção devido às suas características e por funcionar em qualquer ambiente Java.

O Apache Shiro é um framework de segurança para aplicações Java que foca em simplicidade e intuitividade, possuindo um modelo conceitual de fácil entendimento mesmo para aqueles que não possuem grande conhecimento sobre segurança.

Esse framework teve os principais conceitos que envolvem sua utilização apresentados na primeira parte deste artigo. Alguns deles que precisamos lembrar são os seguintes: Subject, Role, Permission, Realm, Hash, Cipher. Assim, antes de prosseguirmos com a prática, faremos uma pequena revisão sobre cada um.

Começando pelo Subject, podemos nos lembrar que ele se refere ao sujeito que está operando o sistema. Não foi usada a palavra User porque quiseram deixar mais genérico, visto que o sujeito não é necessariamente um usuário comum, também pode ser outro sistema, por exemplo. Visto que a API do Apache Shiro é centralizada no Subject, esse será o objeto com o qual mais iremos interagir.

Dois objetos importantes quando falamos de autorização são Role e Permission. Eles descrevem, respectivamente, os papéis que determinado sujeito exerce no sistema e as permissões que esse sujeito tem, direta ou indiretamente. Lembrando que foi discutido sobre o fato de que o ideal é vincularmos, em nosso esquema de banco de dados, os sujeitos a uma lista de papéis e a uma lista de permissões, além de vincular os papéis também a uma lista de permissões. Assim, o sujeito terá uma lista de permissões indiretamente vinculada a ele, que são aquelas vinculadas aos papéis que ele possui, e outra que está diretamente vinculada a ele. Dessa forma, pode-se definir as permissões individualmente e também para um grupo de usuários que possui o mesmo papel no sistema.

Saindo um pouco da utilização e indo para a configuração do Apache Shiro, devemos nos lembrar da importância do Realm. Ele é usado para converter os dados de nosso domínio para o domínio do Apache Shiro. Essa conversão acontece em duas fases: autenticação e autorização. Na autenticação, devemos verificar se determinado sujeito existe em nossa base de dados e, se existe, retornar ao Apache Shiro as informações que ele precisa para fazer a autenticação. Na autorização, devemos retornar as Roles e as Permissions de determinado sujeito.

Além dos conceitos principais, também vimos outras funções realizadas por esse framework, como o gerenciamento de sessão e criptografia. Não abordaremos o gerenciamento de sessão na prática, então resta lembrarmo-nos sobre as formas de criptografia. São elas: Hash e Cipher. O Hash é o tipo de criptografia em que não há como se retornar aos dados iniciais através do resultado do processamento realizado, enquanto o Cipher lhe permite a transformação reversa através da chave usada na encriptação. Veremos, na prática, a utilização de Hash para proteger as senhas dos usuários no banco de dados.

Agora, com os conceitos básicos relembrados, podemos seguir para a implementação de nosso exemplo.

Aplicação prática do Apache Shiro

Com os conhecimentos teóricos, chegou o momento de ir para a prática. Para demonstrar o Apache Shiro em ação, temos uma simples aplicação de publicação de comentários. Basicamente, existirá uma página onde os usuários da aplicação poderão publicar, editar e deletar comentários, de acordo com suas permissões.

Para ilustrar bem a tradução de um domínio de aplicação para o domínio do Apache Shiro através do Realm, foi criada uma estrutura de classes que inclui: Usuario, Papel e Permissao, onde um usuário possui uma lista de papéis e uma lista de permissões, e um papel possui uma lista de permissões.

Na versão inicial da aplicação, onde não há nenhuma segurança aplicada ainda, qualquer usuário pode editar qualquer coisa. Portanto, nosso objetivo é fazer todas as modificações necessárias para fazer um controle de autenticação e autorização através do Apache Shiro.

Por ser um dos frameworks mais utilizados em soluções web, nosso exemplo terá como base o Spring. E para agilizar em seu desenvolvimento, foi utilizado o Spring Roo, que é uma ferramenta de desenvolvimento ágil que, entre outras funções, tem a funcionalidade de gerar código de acordo com um domínio. Por ser uma ferramenta removível, o Spring Roo foi removido ao final do processo, para que não seja necessário que os leitores o instalem ou o entendam. Porém, é importante que se tenha instalado o Maven, que foi usado no controle de dependências e no processo de build da aplicação. Para aqueles que não o conhecerem, não se preocupem. Apenas sigam o tutorial de instalação disponibilizado na área de links e rode os comandos informados neste artigo.

Devido à facilidade de geração das páginas através do Spring Roo, foi utilizado o Spring MVC no lugar de simples Servlets e JSPs. Essa escolha não trará problemas para seguir o tutorial, visto que nenhum conhecimento prévio de Spring MVC será exigido.

Além disso, será adotado um banco de dados em arquivos conhecido como Derby. Esse banco de dados foi escolhido para que os leitores não precisem instalar e configurar um banco de dados como MySQL ou PostgreSQL. Portanto, em razão de os arquivos do Derby já estarem presentes na pasta do exemplo a ser baixado, não será necessária nenhuma configuração extra em relação a banco de dados. Caso queiram ver a configuração realizada, ela está localizada em src/main/resources/META-INF/spring/database.properties. Para utilizar o banco de dados, usaremos o mapeador objeto relacional JPA com Hibernate. Ainda assim, não será necessário conhecimento prévio de JPA e Hibernate, visto que todos os métodos de persistência já foram implementados previamente pelo Spring Roo.

Antes de começarmos, baixe a versão inicial da aplicação no site da revista. Certifique-se de já possuir o Maven instalado para executá-la. Após baixar o arquivo compactado, descompacte em um diretório de sua preferência, vá até esse diretório através do terminal e digite: mvn jetty:run. Esse comando do Maven é responsável por iniciar a aplicação em um servidor Jetty fornecido por um dos plugins. Quando estiver pronto, acesse a aplicação em: localhost:8080/apacheshiro.

Explore a aplicação para notar as ligações entre seus objetos. Perceba as relações, citadas anteriormente, entre usuários, papéis e permissões. Repare também na forma dinâmica como se pode fazer o controle de autorização de usuários dessa forma. Outra coisa importante a se notar é que, no formulário de comentários, podemos simplesmente selecionar qualquer usuário como autor, enquanto deveríamos utilizar o usuário autenticado nesse momento. Portanto, esse será um dos pontos a ser ajustados.

Com o conhecimento da aplicação e dos nossos objetivos, podemos começar a transformá-la em uma aplicação segura com Apache Shiro. O primeiro passo para isso é incluir as dependências necessárias no projeto.

Dependências do Apache Shiro

O Apache Shiro é dividido em módulos, de forma que seus usuários possam adicionar apenas as partes dele que se deseja usar. No nosso caso, precisamos dos seguintes módulos: core, web, spring e aspectj.

O módulo core é sempre necessário em qualquer aplicação que use o Apache Shiro, pois nele está presente todo o núcleo de funcionamento do mesmo. Os outros módulos são incluídos de acordo com a necessidade. O módulo web, por exemplo, só é necessário em aplicações web. Nele estão as classes necessárias para o filtro de URL, gerenciamento de sessão para containers web, entre outras. O módulo spring é necessário para fazer a integração do Apache Shiro com o Spring, de forma que ele será configurado no estilo do Spring, ao invés de usarmos um arquivo INI. E, por último, o módulo aspectj é necessário para usarmos Annotations.

Em uma aplicação comum, nós baixaríamos os arquivos JAR de cada um desses módulos e os colocaríamos no classpath da aplicação. Para aplicações que utilizam o Maven para gerenciar as dependências, nós incluímos o XML mostrado na Listagem 1 dentro da tag <dependencies> do arquivo pom.xml localizado na raiz do projeto.

Listagem 1. Adicionando as dependências no Maven.


    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.2.1</version>
  </dependency>
  <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.2.1</version>
  </dependency>
  <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.2.1</version>
  </dependency>
  <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-aspectj</artifactId>
      <version>1.2.1</version>
  </dependency> ... 

Quer ler esse conteúdo completo? Tenha acesso completo