JAAS – Como utilizar JAAS com JSP + Tomcat

Bom, tendo em vista que muitos desconhecem o que é o JAAS, vou descrever aqui um tutorial de como utilizar deste recurso em sites JSP. Pra quem não conhece, em resumo, JAAS significa “Java Authentication and Authorization Service”, e é um conjunto de APIs criadas para efetuar o controle de autenticação e autorização aos recursos da aplicação, como por exemplo, para web, o controle de login de um site 🙂

O JAAS é nativo da linguagem Java desde a versão 1.4, ou seja, não é necessário baixar nenhum pacote/biblioteca ou plugin para utilizá-lo, e todo container web o implementa, ou seja, o recurso já existe: basta começar a utilizá-lo.

Vantagens da utilização do JAAS
Todo o gerencimento é feito de forma declarativa, ou seja, no deployment descriptor (web.xml), e não programáticamente. Desta forma, não é mais necessário verificar em todas as páginas do servidor se o usuário que está acessando tem permissão de acesso ou não: o JAAS/Container web faz isso automaticamente!

Iniciando a utilização do JAAS
Bom, primeiramente, devemos criar a estrutura da aplicação, ou seja, definir quais recursos serão protegidos. Estes devem estar em um diretório em específico, pois o JAAS faz o controle por diretório.

Olhe a estrutura de diretórios abaixo:

estrutura_projeto

Nela, temos um index.jsp que será a página inicial e dois diretórios: admin e user. Dentro do diretório admin, somente usuários com papel de ADMINISTRADOR poderão acessar, e dentro do diretório user, somente usuários com papel de USUARIO poderão acessar. Esta será nossa estrutura de exemplo.

Existem quatro métodos de autenticação: BASIC, DIGEST, CLIENT-CERT e FORM. Neste tutorial, veremos o uso do método FORM, onde configuramos e criamos as telas de login e senha em HTML.

O próximo passo então é criar as telas de login e de erro de login, que serão chamadas automaticamente quando um usuário tentar acessar um recurso protegido.

Tela de login:

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <title>Login</title>
</head>
<body>

<form method="post" action="j_security_check">
   <table>
      <tr>
         <td>Usuário</td>
         <td><input type="text" name="j_username" /></td>
      </tr>
      <tr>
         <td>Senha</td>
         <td><input type="password" name="j_password" /></td>
      </tr>
      <tr>
         <td><input type="submit" value="Login" /></td>
      </tr>
   </table>

</form>

Observe os dados do formulário: j_username, j_password e j_security_check. Não estão assim de bonito não: é obrigatório que sejam esses os dados! Ao passar estes dados, o container já sabe que será uma requisição para atender com JAAS.

Tela de erro:

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <title>Erro login</title>
</head>
<body>
     <h3>Acesso Negado!</h3>
</body>
</html>

Tela de erro simples, que será mostrada caso o usuário entre com os dados errados no formulário (login e/ou senha incorretos).

Estes arquivos podem ser salvos em qualquer local. No nosso exemplo, serão salvas em jsp.

Agora, o próximo passo é declarar o método de autenticação e as telas de login e erro no web.xml:

<login-config>
	<auth-method>FORM</auth-method>
	<form-login-config>
		<form-login-page>/jsp/login.jsp</form-login-page>
		<form-error-page>/jsp/erroLogin.jsp</form-error-page>
	</form-login-config>
</login-config>

Agora temos de definir os papéis (roles) que a aplicação irá trabalhar. Abaixo, como configurar as roles no web.xml:

<security-role>
	<role-name>ADMINISTRADOR</role-name>
</security-role>

<security-role>
	<role-name>USUARIO</role-name>
</security-role>

Com as roles definidas, agora é necessário declarar os recursos a serem protegidos. No web.xml:

<security-constraint>
	<web-resource-collection>
		<url-pattern>/admin/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<role-name>ADMINISTRADOR</role-name>
	</auth-constraint>
</security-constraint>

<security-constraint>
	<web-resource-collection>
		<url-pattern>/user/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<role-name>USUARIO</role-name>
	</auth-constraint>
</security-constraint>

Tá… mas e o cadastro de usuários?
Pode ser feito de várias formas (Banco de dados, xml, properties, etc), e cada container tem sua própria implementação. Para este exemplo, vamos ver a forma mais básica no Tomcat: cadastrar os usuários no $TOMCAT_HOME/conf/tomcat-users.xml:

<tomcat-users>
  <role rolename="ADMINISTRADOR"/>
  <role rolename="USUARIO"/>
  <user username="admin" password="123" roles="ADMINISTRADOR, USUARIO"/>
  <user username="user" password="123" roles="USUARIO"/>
</tomcat-users>

No exemplo acima, cadastramos um usuário “admin” com as roles de ADMINISTRADOR e de USUARIO, ou seja, este usuário tem os dois privilégios (acessa os dois diretórios). Já o usuário “user” tem acesso apenas ao diretório user.

Já vimos uma das grandes vantagens do JAAS: efetuar o controle de autenticação e autorização totalmente de forma declarativa, ou seja, sem colocar a mão em nenhum código fonte Java.

Bom, o post termina por aqui: em uma outra oportunidade irei explicar como utilizar o JAAS com banco de dados.

Espero ter ajudado.

Abraço!

Deixe um Comentário

12 Comentários.

  1. Boa noite, Hallan, tenho a seguinte dúvida: Meu site tem um link para cadastro de users, que está na mesma página de login, ou seja, o login no sistema ainda não foi feito. Então, como posso permitir que uma pessoa se cadastre uma vez que não existe um user logado no jaas neste momento?
    Obrigado pela atenção.

  2. Everton: para permitir que uma pessoa se cadastre, o diretório onde encontra-se a página de cadastro não pode estar protegida. Lembrando que no JAAS você define quais diretórios precisarão de uma determinada role para acesso, ou seja, podem existir diretórios com acesso livre. Exemplificando:

    Se você tiver esta estrutura de diretórios:
    ../portal/
    ../cadastro/

    Podemos dizer que para acessar o conteúdo da pasta “portal”, o usuário tem que estar logado, mas o diretório “cadastro” tem livre acesso: ali podem estar as páginas de cadastro.

    Isso ficaria assim no web.xml:

    <security-constraint>
    <web-resource-collection>
    <url-pattern]/portal/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
    <role-name>USUARIO</role-name>
    </auth-constraint>
    </security-constraint>

    ou seja, tudo que está fora do /portal/ não precisa estar logado para acessar. E para acessar o conteúdo de /portal/, é necessario estar logado com a role de USUARIO.

    No JAAS, tudo depende da estrutura de diretórios da aplicação.

    Não sei se fui claro, mas é mais ou menos por ai.

    Abraço!

  3. Olá Halan, muito bom artigo, tem alguma previsão do post utilizando banco de dados. Grato desde já e abraço.

  4. opa! Hallan,

    Excelente post! parabens! ficou devendo com BD. 😀

  5. Cara vc me salvou vlws!
    eu não tava considerando a estrutura de botar nas pastas tava deixando tudo solto e não tava dando certu!
    obrigado

  6. Olá!
    Excelente tutorial, entretanto, aqui na minha máquina, mesmo seguindo rigorosamente seu exemplo ele sempre aparece acesso negado.
    Qualquer dica sera muito bem vinda!
    Obrigado e parabéns!
    Marcos

  7. Dae Hallan,

    Blog com a cara nova…fico legal.
    Vamos ver o que podemos fazer com o JAAS…valeu
    Agente se fala.

  8. Gustavo Carvalho

    Não está mostrando a imagem da estrutura do projeto 🙂

Deixe um Comentário


NOTA - Você pode usar estesHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>