Segurança JEE Realm FORM TomCat

olá Pessoal,

Hoje vou falar de um assunto que todos os desenvolvedores, arquitetos etc. tem que se preocupar ao desenvolver uma aplicação é a famosa segurança. Você como “profissional do software” tem que saber quem vai ter acesso a determinadas partes da sua aplicação e o que ele pode fazer após ter concedido o acesso.

Dizer  se o usuário “camilo” for um simples “user” ele só pode navegar nas seguintes pages: “index.jsp, faleconosco.jsp etc”. Agora vamos dizer que o usuário “lopes” é um dos administradores do sistema, então ele pode acessar as páginas “cadastrarprodutos.jsp, deletarusuario.jsp que estão em /admin” etc.

Como fazer isso Camilo?

Bem, o objetivo deste post é dar um suporte quem está entrando agora no mundo JEE, hoje temos frameworks que ajudam de forma mais eficiente que usar Realm do TomCat. Mas, não pretendo ir além do Realm. Só ele dar um big post.

Alguns iniciantes em JavaEE, tem essa dúvida consigo: como implementar regra de acesso sem precisar fazer um hard-code?”

Fazer isso dentro do seu servlet, controller etc. não é boa ideia pelo simples motivo: “as regras de segurança podem mudar com bastante frequência”. Como por exemplo amanha você precisa adicionar um novo nível de administrador (sênior, pleno) e cada um com permissões diferentes. Mas, também pode acontecer de um novo grupo fazer parte da administração os “gerente de projetos” ai lá vai o desenvolvedor atualizar o code e se amanhã deixar de existir algum dos citados? Já viu o prolema que temos ao implementar regras de segurança dentro do seu servlet, controller etc.

Os iniciantes em JEE, põe tudo que for restrito dentro de WEB-INF, isso não é boa prática.

As regras de segurança referente acesso é algo que pode ser simples, mas também complexo, vai depender da regra de negócios da aplicação. Por exemplo, já vi aplicações que tem vários tipos de administradores, usuários, com acessos completamente diferentes, porém no mesmo nível. Mas, colocar em WEB-INF todos as suas pages .jsp. Vc deve se perguntar: “é seguro a quem?”.

Vamos parar de conversa e veremos na prática…

lets go…

Realm

Realm é um depósito de informações de usuário que autentica e autoriza os usuários.Usando realms, você põe a responsabilidade no servidor Web por obrigar a implementar políticas de segurança. Isto significa que os desenvolvedores não precisam escrever código para usar autenticação e autorização (não que isso os impeçam de fazê-lo). Delegando autenticação e autorização ao servidor, os desenvolvedores podem escrever códigos de propósitos gerais, sem preocupação com as regras de autorização de acesso. (Livro – Tomcat – Guia Rápido do Administrador)

Para esse exemplo vamos usar um dos mais populares container JEE o TomCat (versão 6). Se você estiver usando um container diferente, terá que ler a documentação do fabricante e saber como implementar. Porém há poucas mudanças na maioria das vezes.

Posts Recomendado:

Requisitos:

  • Eclipse (usarei o Galileo)

  • TomCat 6 (se tiver a 5.x.x sem problemas, pode usar)

Aqui vamos implementar sem usar dados vindo do BD. Então veja como uma forma de praticar “Segurança” até porque sem BD, vc vai precisar sempre ficar atualizando o arquivo tomcat-users.xml e se você não usar criptografia, qualquer um pode abrir esse arquivo e saber as senhas de cada usuário.

Desenvolvendo

  1. Crie um dynamic web project no Eclipse e deixe ele conforme a imagem a seguir. O meu chama RealmCamilo no decorrer do post, estarei informado o que teremos em cada page .jsp.

  2. Na página acessonegado.jsp insira o código a seguir:

    E-mail/Senha inválido.Tente novamente  />
  3. Na página index.jsp deixe conforme abaixo

     Acessar minha conta
  4. agora na pagina index.jsp dentro de /admin deixe assim:

    Está é uma página de conteúdo restrito. 🙂

Até aqui nada de especial. Agora que começa a segurança.

  1. Primeiro ponto é você deixar o tomcat parado e ir no caminho a seguir (caso tenha instalado no modo default):

    C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf

  2. Abra o arquivo server.xml

    Precisamos dizer ao TomCat que vamos habilitar o Realm, a linha vem comentada, para isso tire o comentário da linha a seguir:

    <Realm className=”org.apache.catalina.realm.MemoryRealm”/>

  3. Salve e feche o arquivo

  4. Agora vá no arquivo tomcat-users.xml no mesmo diretório do arquivo server.xml.

    Nesse arquivo criamos os usuários que terão acesso aplicação e qual role ele pertence.

    rolecode

  5. Não é muito difícil de ler, veja:

    “lopes É-UM manager. Porém, admin e camilo são um manager e admin.”

  6. O relacionamento aqui é one-to-many, nao se esqueça disso. Ou seja, um usuário pode ter mais de um nível de acesso.

  7. Lembre-se isso ai só são strings. O poder deles está quando criamos as restrições no arquivo web.xml.

Criando as regras de acesso

Agora precisamos criar as regras de acesso, dizer o que um “manager” pode acessar e o que um “admin”pode acessar.

  1. Abra o arquivo web.xml da sua aplicação.

webxml

Antes do primeiro código você precisa saber disso:

  • <security-constraint>: Protege um recurso, ou seja, diz o que será protegido e quem pode acessar.

  • <auth-constraint>: Isto especifica os roles que são permitidos acessar recursos cobertos por esta limitação de segurança.

  • <web-resource-collection>: sub-elemento de <security-constraint> que diz o que será registro.

  • <login-config>: diz qual o tipo de autenticação. Há quatros tipos: BASIC, DIGEST, FORM, SSL.

Para o nosso exemplo usaremos o FORM. O BASIC ele usa a caixa de autenticação do browser.

  1. insira o código abaixo no seu arquivo web.xml


Atenção:

Agora tenha atenção com o código de <login-config> Muitos confundem, achando que se o login/senha estiver OK. Vá para a página que está em <form-login-page> , mas ali que temos nenhuma condição IF.

O segredo é que antes de ir para tela de login, vc precisa ter tentando acessar o conteúdo restrito(na realidade é isso que acontece, pense um pouquinho…), assim o servidor vai saber o que fazer com vc que acessar caso seu login/senha válido, ou seja, enviar você para a página que foi solicitada (requested).

Se você, tentar direto para página de login, sem tentar acessar um conteúdo restrito, como o servidor vai saber encaminha-lo? Já que no action do form não há nada que diz “vá para pagina XYZ”.

  1. veja o código do form login.jsp

    Login
    Usuario: Senha:
  2. O atributo name, action deve ser com os nomes acima. Caso contrário, nada funciona como esperado. E nao esqueça que o método deve ser post, pois é um FORM.

Eu tenho o hábito de dizer: “Primeiro erre, para depois acertar”. Ou seja, primeiro tente acessar se não conseguir use seu login/senha. O máximo que vai receber é dizer que você não tem permissão para acessar.

Testando

*não esqueça dos starts/stops que você deve dar sempre que atualizar os arquivos .xml do tomcat.

Para testar vamos fazer um deploy da nossa app. Vamos usar um arquivo WAR, se não sabe como exportar um projeto como WAR veja no post indicado no inicio do post.

Abaixo como ficou minha exportação:

Veja meus teste de acesso:

  1. Tentando com o usuário camilo


  2. Resultado:


  3. Tentando com o usuário lopes


  4. Resultado:


Agora é com você

Experimente testar acessando o conteúdo restrito direto, tente colocar usuário inexistente, ou usuário com roles diferentes ao acesso permitido. E para ficar uma mensagem de erro personalizada, crie suas proprias páginas de erro.

Bom ficando por aqui, acho que este foi um dos maiores posts que já escrevi e nao sou a favor de posts grandes, mas foi necessário. O assunto precisava ser detalhado e olha que nao fui tanto assim. Vi vários outros posts na internet porém os que encontrei estava resumido demais e para quem está dando os primeiros passos pode se tornar complicado o processo. Espero que tenham gostado.

Abraços, see you next post. :).

7 comentários em “Segurança JEE Realm FORM TomCat”

    1. olá Diogo, demorei de responder pois estava de ferias. vamos lá. Bem, eu usei o realm com bd tem um bom tempo, e nao lembro se cheguei a fazer um post aqui no blog a respeito eu acho que sim. Enfim, é horrivel, implementar BD com ele. Eu mudei para o SpringSecurity e recomendo vc usa-lo, tem um post aqui no blog, a respeito e citacoes a outros posts, vc resolve isso em 10min. Eu na epoca que mexia com realm gastava horas qdo envolvia BD. A respeito de sua ultima pergunta. pq vc nao chama as paginas que ficam dentro de cada path admin/ algo como index.jsp assim automcatimaticamente ela será aberta ao acessar, mas se vc quer personalizar que tipo de página pode ser chamado como default, vc precisa atualizar a tag welcome -file-list que temos. E para usar com BD vc precisa registrar o jdbc la em um arquivo no tomcat, com uma linha de comando, e sua aplicacao fica refem do tomcat, se quiser usar jetty, vai ter que refazer toda a parte de seguraça, percebeu o problema? me envia um email que envio uns docs que tenho que usei na epoca que queria fazer isso. acho que pode ti ajudar, se ainda deseja implementar com BD.
      abracos,

  1. so uma pergunta como eu faço para a senha nao ficar gravada na sessao , pois toda a hora que a pessoa acessar as paginas restritas quero que seja pedido a senha do administrador e depois da primeira autenticação e entra direto ..

    1. ola clayton,

      use o SpringSecurity, o Realm é mais para sistema legado veja neste post http://www.edsongoncalves.com.br/category/spring/ e mais facil fazer o que vc quer via SS. Há varias formas de controlar uma sessao, vc pode fazer via servlet, deixar o servidor decidir isso, e depender do front-end que esteja usando é possivel fazer isso la no front-end tb. depois que vc conhecer o SS nunca mais vai querer saber de Realm na sua vida.

Deixe um comentário para clayton Cancelar resposta

O seu endereço de e-mail não será publicado.