Conhecendo a segurança declarativa do Java (JAAS) – Parte 1

Escrito por paulovittor23, 16 de Outubro de 2007 13:33

Afinal, o que é esse JAAS ?

O JAAS ou “Java Authentication and Authorization Service” é um conjunto de API’s que visam desacoplar as aplicações dos controles de acesso a recursos da mesma, ficou bonita essa frase hein ? na prática isso significa retirar do desenvolvedor a responsabilidade de ter que controlar o acesso a recursos por perfis de maneira programática( filtros e outros meios ilicitos que eu também já fiz /o\ ). Todo o controle passa a ser feito de maneira declarativa no descritor da aplicação, daí o nome segurança declarativa, intuituivo, não ?

Basicamente o JAAS pode ser atilizado para dois propósitos:
- Autenticação de usuários, ou seja, verificar se o usuário é registrado;
- Autorização de usuários, ou seja, verificar se o usuário já autenticado tem permissão de acesso para determinado recurso protegido;

Tá, mas…o que eu ganho usando o JAAS ?

Muitas coisas, você passa a se preocupar de fato com o código que é importante para a sua aplicação, as restrições a determinados recursos não vão mais interferir na maneira como você desenvolver sua aplicação, você pode por exemplo após ter concluído o desenvolvimento fazer as devidas declarações de quais recursos serão protegidos e quem poderá acessá-los. Implicitamente isso tornará seu código mais legível e focado nas regras de negócio. Sem contar que qualquer modificação nas restrições implicará na mudança de apenas um arquivo(web.xml) e não mais em diversos pontos espalhados pela aplicação.

Tudo muito legal, mas….como eu implemento isso ?

Para demonstrar como implementamos o JAAS vamos sugerir um cenário…
Suponhamos que em sua aplicação você tenha um recurso(neste caso uma JSP…obviamente poderia ser qualquer outra coisa, como servlets, imagens, enfim…) e que você deseje que apenas usuários devidamente autenticados e autorizados possam visualizar essa página.
Para ficar mais fácil a compreensão abaixo esta disposta a estrutura da aplicação onde iremos aplicar os conceitos do JAAS para resolvermos o problema proposto no cenário…
obs.: todos os elementos de relevância serão detalhados na seguência…

01.JPG

Eu chamei a aplicação de “Security”, e nela tenho o meu diretório de conteúdo (WebContent) onde tenho o diretório “WEB-INF”, minha JSP que irá ser mapeada para ser a página de boas vindas(index.jsp) e outro diretório chamado “jsp”. Neste diretório “jsp” temos a “home.jsp” que será a nossa página de acesso restrito e outro diretório chamado “security” onde vamos criar a tela de login(login.jsp) e a tela de erro apresentada caso o login seja falho(error_login.jsp).

Um dos métodos de autenticação de usuário do JAAS consiste em um mecanismo baseado em formulário de autenticação, formalmente conhecido como FORM, que é o método que será abordado neste artigo. Mas a título de conhecimento existem mais três métodos de autenticação que são o DIGEST, o BASIC e o CLIENT-CERT

Como declaramos qual será o método de autenticação que usaremos ?


No seu deployment descriptor você deverá inserir as seguintes declarações..

<login-config>
<!–INDICA O METODO DE AUTENTICAÇÃO –>
<auth-method>FORM</auth-method>

<form-login-config>
<!–INDICA A JSP DE LOGIN –>
<form-login-page>/jsp/security/login.jsp</form-login-page>

<!–INDICA A PAGINA A SER CAHAMADA CASO O LOGIN SEJA FALHO –>
<form-error-page>/jsp/security/error_login.jsp</form-error-page>
</form-login-config>
</login-config>

Com a declaração acima, estamos dizendo ao container para usar as telas de login,jsp e error_login.jsp para tratar a autenticação, portanto, devemos agora implementar essas JSP’s..

login.jsp

<%@ page language=”java” contentType=”text/html; charset=ISO-8859-1″
pageEncoding=”ISO-8859-1″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>LOGIN</title>
</head>
<body>
<form action=”j_security_check” method=”POST”>
username: <input type=”text” name=”j_username” /><br />
password: <input type=”password” name=”j_password” /><br />
<input type=”submit” value=”login” />
</form>
</body>
</html>

IMPORTANTE:
A propriedade action do formulário deve conter o valor “j_security_check”, o campo que receberá o nome do usuário deverá se chamar “j_username” e o campo que receberá a senha deverá se chamar “j_password”. Sim, se você mudar algum desses valores obrigatorios sua autenticação terá dois possíveis caminhos…erro durante a execução ou ninguém nunca se conseguirá autenticação…

error_login.jsp

<%@ page language=”java” contentType=”text/html; charset=ISO-8859-1″
pageEncoding=”ISO-8859-1″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>LOGIN</title>
</head>
<body>
<p>Usuário e/ou Senha inválidos !</p>
<a href=”javascript:history.go(-1);”>Tentar Novamente</a>
</body>
</html>

Declarando os “papéis” ou “perfis” de usuário que sua aplicação trabalhará…

No web.xml você deve declarar todas os perfis de usuários ou papéis aos quais os usuários poderão ser atribuidos…no nosso caso vamos criar a role “web_user”

<!– ROLES DE SEGURANÇA –>
<security-role>
<role-name>web_user</role-name>
</security-role>

Implementando a “home.jsp”…

<%@ page language=”java” contentType=”text/html; charset=ISO-8859-1″ pageEncoding=”ISO-8859-1″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>HOME</title>
</head>
<body>
Welcome, ${userPrincipal.name} !
</body>
</html>

Restringindo a página “home.jsp” a usuários que possuam o “papel” de “web_user”…

Bom, para restringir o acesso de “algo” usando JAAS devemos seguir o conceito de que esse “algo” é um recurso, então dentro da tag de restrição de segurança nós mapeamos um recurso pela URL e atribuimos um nome a este recurso…nesta deficição podemos também especificar o método HTTP que deve ser tratato…lembrando que a não deficição dos métodos HTTP faz com que ambos GET e POST sejam tratados…
Logo em seguida, estamos definindo quais são os “papéis” que poderam ter acesso ao recurso mapeado…

<!– MAPEAMENTO DA SEGURANÇA –>
<security-constraint>

<web-resource-collection>
<web-resource-name>home</web-resource-name>
<url-pattern>/jsp/home.jsp</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>

<auth-constraint>
<role-name>web_user</role-name>
</auth-constraint>

</security-constraint>

Definindo e implementando a página de boas vindas ou welcome-file da nossa aplicação..

Para definirmos a página que será chamada quando o usuário acessar o “document root” da aplicação nos acrescentamos ao nosso arquivo web.xml o seguinte trecho de código..

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

Segue abaixo a implementação desta página…

index.jsp

<%@ page language=”java” contentType=”text/html; charset=ISO-8859-1″
pageEncoding=”ISO-8859-1″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + “://” + request.getServerName() + “:” + request.getServerPort() + path + “/”;
%>
<html>
<head>
<base href=”${basePath}” />
<title>INDEX.JSP</title>
</head>
<body>
<a href=”jsp/home.jsp”>HOME ( recurso protegido )</a>
</body>
</html>

Bom, estamos quase terminando…
falta agora definirmos os usuários e os papéis que cada usuário poderá exercer na aplicação… para isso existem algumas formas de armazenar esses usuários e suas respectias responsabilidades. Esse foi o fator pelo qual separei esse artigo em 2 partes. Neste primeiro momento vamos armazenar essas informações em arquivos de propriedades que ficaram em nosso container, na segunda parte deste artigo nós aprimoraremos um pouco este exemplo fazendo com que as informações sejam armazenadas em um banco de dados.

Definindo os arquivos de propriedades…

Precisaremos crirar dois arquivos de propriedades, o “users.properties” e o “roles.properties”
o users.properties é o arquivo onde iremos armazenar os usuários e suas respectivas senhas
já o arquivo roles.properties é onde iremos associar ao usuário os papéis que ele poderá desempenhar na aplicação…

users.properties

root=123

roles.properties

root=web_user

Agora que já temos em mãos os arquivos necessários é só colocarmos esses arquivos no diretório “jboss-X.X.X.GA\server\default\conf“…lembrando que estas configurações são para se trabalhar com o JBoss…cada container tem a sua maneira de implementar essas configurações…

Pronto, agora basta inicializarmos o servidor e via browser tentar acessar nossa aplicação…
a página “index.jsp” será apresentada. Nela haverá um link para o recurso protegido(home.jsp) que quando acionado automaticamente requisitará a autenticação do usuário…Para conseguir acesso utilize “root” e “123” como usuário e senha respectivamente…

Qualquer dúvida ou falha no artigo por favor notifique… =)

15 Comentários “Conhecendo a segurança declarativa do Java (JAAS) – Parte 1”

  1. Monstro diz:

    Tipo, nao existe nenhuma configuração estilo anotações!?? xml sux a lot!! ^^

  2. paulovittor23 diz:

    Pela especificação, toda a configuração do JAAS é feita pelo descritor da aplicação…porém, existem algumas alternativas “fora do padrão” como o “Security Annotation Framework”(http://safr.sourceforge.net/) ou se você quiser anotações e ainda mais controle sobre a segurança, por exemplo a ponto de dizer que um método só pode ser acessado por um usuário em determinado horário e se ele pertencer a um determinado perfil existem recursos mais evoluídos como JBoss Seam + Jboss Rules…estes sim em breve virarão padrão no Java EE 6…
    Estou estudando o assunto…futuramente comentarei algo mais detalhado sobre o assunto aqui no blog =)
    Mas eu acredito que a configuração do JAAS via xml, em aplicações de pequeno e médio porte, sejam ideais…

    ps: próximo final de semana estarei postando a segunda parte do artigo… XD

  3. Monstro diz:

    kd o artigo sobre JBOSS Seam!? hehe

  4. Ariel diz:

    Eu tenho uma dúvida!
    Aparentemente é impossível fazer com que o Adsense logue nas paginas protegidas por esse método. Realmente é isso mesmo? Você já testou? Minhas paginas são todas protegidas assim e vou ter que mudar tudo graças ao Adsense…

  5. Christopher diz:

    Muito legal esse tipo de autenticação… só tenho uma dúvida…. as senhas no arquivo de configuração… ficam desprotegidas mesmos… quero dizer, não dá pra deixá-las criptografadas ?

    Grato.

  6. Rick diz:

    Very Nice! Thanks!

  7. Thiago diz:

    Muito bom essa explicação, agora como faço pra usar JASS em uma aplicação JSF usando oc4j, agradeço!

  8. leou1000d diz:

    Muito bom cara, parabéns, tow testando, vlw!

  9. Opa, publicaçao muito boa, já tem previsão para a “Parte 2″

  10. Rafael diz:

    Paulo,

    Executei os passos acima com o maximo de exatidão possivel, porém quando executo o login o processo fica travado no j_security_check. Você sabe porque isso poderia ocorrer?

    Grato

    Rafael

  11. Flávio diz:

    Estou desenvolvendo uma aplicação com JAAS, com a mesma estrutura do seu projeto de exemplo.

    Quando eu informo usuário e senha incorretos, funciona. redirecionando para a mesma página de login. Quando, porém, informo usuário e senha corretos, dá o seguinte erro:

    HTTP Status 400 – Invalid direct reference to form login page

    O que pode estar acontecendo de errado?

    Obrigado.

    Flávio

  12. Franciela Nissola diz:

    Paulo….
    Gostaria de saber se publicou a parte 2 da autenticação com JAAS , pegando os dados no DB???? Estou implementando…..e estudando sobre isso…
    Se tiveres, desde já agradeço

  13. Everton diz:

    Boa noite, Paulo, 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.

Deixe o seu comentário!

Panorama Theme by Themocracy