Você está na página 1de 14

Como usar JAAS com Tomcat 6.

1) Passos para criar o módulo de autenticação e autorização

a) Crie novo “Java Project”;

Ex.:
AppLoginModuleJAAS

b) Nele, crie 2 pacotes;

Ex.:
br.pro.passos.security
br.pro.passos.security.principal

c) No primeiro pacote, crie uma classe, digamos “LoginModuleJAASImpl”, que


implemente a interface “LoginModule”;
d) No segundo pacote, crie as classes “UsuarioImplPrincipal” e “PapelImplPrincipal”, que,
como o nome sugere, implementem a interface “Principal”;
e) Compile o projeto para um arquivo de nome “LoginModuleJAAS.jar”;
f) Coloque o arquivo “LoginModuleJAAS.jar”, criado em “e”, no diretório “lib” do Tomcat;
g) Crie um arquivo “jaas.config” com o conteúdo abaixo:

ModuloLoginJAAS {
br.pro.passos.security.LoginModuleJAASImpl required;
};

h) Coloque o arquivo “jaas.config”, criado em “g”, no diretório “conf” do Tomcat;


i) Insira no arquivo “catalina.bat”, presente no diretório “bin” do Tomcat, antes da linha
comentada “Execute The Requested Command”, a linha abaixo:

set JAVA_OPTS=%JAVA_OPTS% -Djava.security.auth.login.config="%CATALINA_BASE%\conf\jaas.config"

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 1


Como usar JAAS com Tomcat 6.0

2) Passos para criar aplicativo web escrito em Java para testar o módulo de
autenticação e autorização

a) Crie novo “Dynamic Web Project”.

Ex.:
AppWebTestaJAAS

b) No diretório “WebContent”, crie as páginas JSP:

index.jsp
login.jsp
erroLogin.jsp
erro403.jsp
logout.jsp
cadastros.jsp
relatorios.jsp

Os códigos-fonte dessas páginas encontram-se no fim deste documento. Vamos


comentar apenas alguns poucos trechos.

Na página “login.jsp”, deve-se notar o valor do atributo “action” (j_security_check) e dos


atributos “name” dos campos type (j_username)e password (j_password).

<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 colspan="2"><input type="submit" value="Login" /></td>
</tr>
</table>

Na página “logout.jsp”, código-abaixo, observe que a sessão é finalizada e o usuário é


redirecionado para a página “index.jsp”, o que, por sua vez, levará o usuário para a
página de login novamente.

<%
session.invalidate();
response.sendRedirect("index.jsp");
%>

Nas páginas “index.jsp”, “cadastros.jsp”, “relatórios.jsp” e “erro403.jsp”, a linha abaixo


é responsável por exibir uma saudação personalizada para o usuário autenticado.

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 2


Como usar JAAS com Tomcat 6.0

<h3>Olá, <%= request.getRemoteUser() %>!!!</h3>

c) No diretório “META-INF”, crie um arquivo “context.xml” com o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>


<Context auth="Container">
<Realm className="org.apache.catalina.realm.JAASRealm"
appName="ModuloLoginJAAS"
userClassNames="br.pro.passos.security.principal.UsuarioImplPrincipal"
roleClassNames="br.pro.passos.security.principal.PapelImplPrincipal" />
</Context>

Observe que atribuímos a “appName” o nome dado ao módulo de autenticação e


autorização no arquivo “jaas.config”.

Observe também que usamos o nome totalmente qualificado das classes que
representam os usuários e os papéis.

d) No arquivo “web.xml”, inclua as linhas:

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

<security-constraint>
<display-name>Política de segurança do sistema</display-name>
<web-resource-collection>
<web-resource-name>Protege todo o site</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>AUTENTICADO</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<description>Papel requerido para acessar quaisquer recursos do aplicativo</description>
<role-name>AUTENTICADO</role-name>
</security-role>

<error-page>
<error-code>403</error-code>
<location>/erro403.jsp</location>
</error-page>

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 3


Como usar JAAS com Tomcat 6.0

Em <security-constraint>, definimos a política de acesso ou as restrições de segurança.


No exemplo, estabelecemos que apenas usuários com status, perfil, papel ou função
“AUTENTICADO” poderão acessar o aplicativo.

Aos papéis, <role-name>, de <security-constraint> devem corresponder <role-name>


em <security-role>.

Em <login-config>,estabelecemos a forma de autenticação. Neste exemplo, FORM.


Também mapeamos as páginas de login e erro de login. Ou seja, informamos a página
em que o usuário informará seu nome de usuário (username) e senha (password), e a
página que será exibida se a autenticação falhar (usuário e senha não conferem).

Se o usuário for autenticado, mas não tiver permissão, autorização, para acessar um
recurso, ocorrerá o erro 403, e a página erro403.jsp será exibida.

e) A organização das páginas JSP e dos arquivos XML do aplicativo deve ser com abaixo:

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 4


Como usar JAAS com Tomcat 6.0

3) Códigos-fonte das classes do módulo de autenticação e autorização

Classe UsuarioImplPrincipal.java

package br.pro.passos.security.principal;

import java.security.Principal;

public class UsuarioImplPrincipal implements Principal{


private String name = null;

public UsuarioImplPrincipal(String name) {


super();
this.name = name;
}
public String getName() {
return name;
}
}

Classe PapelImplPrincipal.java

package br.pro.passos.security.principal;

import java.security.Principal;

public class PapelImplPrincipal implements Principal {


private String name = null;

public PapelImplPrincipal(String name){


this.name= name;
}
public String getName() {
return this.name;
}
}

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 5


Como usar JAAS com Tomcat 6.0

Classe LoginModuleJAASImpl.java

package br.pro.passos.security;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import br.pro.passos.security.principal.PapelImplPrincipal;
import br.pro.passos.security.principal.UsuarioImplPrincipal;

public class LoginModuleJAASImpl implements LoginModule {

protected Subject subject = null;


protected CallbackHandler callbackHandler = null;
protected Map sharedState = null;
protected Map options = null;

protected Callback[] callbacks = null;


protected Set principals = null;
UsuarioImplPrincipal usuario = null;
PapelImplPrincipal papel = null;

String username = null;


String password = null;

private boolean loginComSucesso = false;


private boolean commitComSucesso = false;

Map senhas = new HashMap();

public void initialize(Subject subject, CallbackHandler callbackHandler,


Map sharedState, Map options) {

this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 6


Como usar JAAS com Tomcat 6.0
this.senhas.put("fulano", "a");
this.senhas.put("beltrano", "b");
this.senhas.put("cicrano", "c");
}

public boolean login() throws LoginException {


this.tratarCallback();

this.username = this.getUsername();
this.password = this.getPassword();

if (this.username!=null && this.password!=null){


String senha = (String)this.senhas.get(username);
if (senha!=null && senha.equals(this.password)){
this.loginComSucesso = true;
}
}

return this.loginComSucesso;
}

public boolean commit() throws LoginException {


if ( this.loginComSucesso == true ) {
this.adicionaPrincipals();

//sharedState.put("javax.security.auth.principal", this.usuarioPrincipal);
//sharedState.put("javax.security.auth.roles", this.perfilPrincipal);

this.commitComSucesso = true;
}

return this.commitComSucesso;
}

public boolean abort() throws LoginException {


if( loginComSucesso == false ) {
return false;
} else if( loginComSucesso == true && commitComSucesso == false ) {
loginComSucesso = false;
username = null;
password = null;
usuario = null;
papel = null;
} else {
logout();
}

return true;
}

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 7


Como usar JAAS com Tomcat 6.0

public boolean logout() throws LoginException {


subject.getPrincipals().remove(usuario);
subject.getPrincipals().remove(papel);
loginComSucesso = false;
commitComSucesso = false;
username = null;
password = null;
usuario = null;
papel = null;

return true;
}

private void tratarCallback() throws LoginException {


this.callbacks = new Callback[2];
this.callbacks[0] = new NameCallback("Usuario: ");
this.callbacks[1] = new PasswordCallback("Senha: ", false);

try {
this.callbackHandler.handle(this.callbacks);
} catch(IOException ie) {
throw new LoginException("Capturada IOException lançada pelo método
tratarCallbacks()");
} catch(UnsupportedCallbackException uce) {
throw new LoginException("Capturada UnsupportedCallbackException lançada pelo
método executarCallback()");
}
}

private String getUsername() {


String j_username = null;
for (int i = 0; i < this.callbacks.length; i++) {
if (this.callbacks[i] instanceof NameCallback) {
j_username = ((NameCallback)this.callbacks[i]).getName();
break;
}
}

return j_username;
}

private String getPassword() {


String j_password = null;
for ( int i = 0; i < this.callbacks.length; i++){
if ( this.callbacks[i] instanceof PasswordCallback) {
j_password = new String(((PasswordCallback)this.callbacks[i]).getPassword());
break;
}

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 8


Como usar JAAS com Tomcat 6.0
}

return j_password;
}

protected void adicionaPrincipals() {


this.usuario = new UsuarioImplPrincipal(this.username);
this.papel = new PapelImplPrincipal("AUTENTICADO");

if (!subject.getPrincipals().contains(usuario)) {
subject.getPrincipals().add(this.usuario);
}

if (!subject.getPrincipals().contains(papel)) {
subject.getPrincipals().add(this.papel);
}
}
}

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 9


Como usar JAAS com Tomcat 6.0

4) Códigos-fonte do aplicativo web de teste

Página 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"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>AppWebDemoJAAS - index.jsp</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 colspan="2"><input type="submit" value="Login" /></td>
</tr>
</table>
</form>
</body>
</html>

Página erroLogin.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"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%session.invalidate();%>
<h3>Usuário ou senha inválida!!!</h3>
<input type="button" value="Voltar"
onclick="javascript:document.location='index.jsp'" />
</body>
</html>

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 10


Como usar JAAS com Tomcat 6.0

Página logout.jsp

<%
session.invalidate();
response.sendRedirect("index.jsp");
%>

Página erro403.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"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>Olá, <%= request.getRemoteUser() %>!!!</h3>
<% if (!request.isUserInRole("AUTENTICADO")) { %>
<p>Somente usuários <b>AUTENTICADOS</b> podem acessar este recurso.</p>
<% } %>
<%session.invalidate();%>
<input type="button" value="Home"
onclick="javascript:document.location='index.jsp'" />
</body>
</html>

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"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>Olá, <%= request.getRemoteUser() %>!!!</h3>
<p>Escolha uma opção:</p>
<input type="button" value="Cadastros"
onclick="javascript:document.location='cadastros.jsp'"/>
<input type="button" value="Relatórios"
onclick="javascript:document.location='relatorios.jsp'"/>
<input type="button" value="Logout" onclick="javascript:document.location='logout.jsp'"/>
</body>
</html>

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 11


Como usar JAAS com Tomcat 6.0

Página cadastros.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"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>Olá, <%= request.getRemoteUser() %>!!!</h3>
<p>Escolha uma opção:</p>
<input type="button" value="Home" onclick="javascript:document.location='index.jsp'"/>
<input type="button" value="Relatórios"
onclick="javascript:document.location='relatorios.jsp'"/>
<input type="button" value="Logout" onclick="javascript:document.location='logout.jsp'"/>
</body>
</html>

Página relatorio.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"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>Olá, <%= request.getRemoteUser() %>!!!</h3>
<p>Escolha uma opção:</p>
<input type="button" value="Home" onclick="javascript:document.location='index.jsp'"/>
<input type="button" value="Cadastros"
onclick="javascript:document.location='cadastros.jsp'"/>
<input type="button" value="Logout" onclick="javascript:document.location='logout.jsp'"/>
</body>
</html>

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 12


Como usar JAAS com Tomcat 6.0

5) Arquivos XML

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context auth="Container">
<Realm className="org.apache.catalina.realm.JAASRealm"
appName="ModuloLoginJAAS"
userClassNames="br.pro.passos.security.principal.UsuarioImplPrincipal"
roleClassNames="br.pro.passos.security.principal.PapelImplPrincipal" />
</Context>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>AppWebTestaJAAS</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>default</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/erroLogin.jsp</form-error-page>
</form-login-config>
</login-config>
<security-constraint>
<display-name>Política de segurança do sistema</display-name>
<web-resource-collection>
<web-resource-name>Protege todo o site</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>AUTENTICADO</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<description>Papel requerido para acessar quaisquer recursos do aplicativo</description>
<role-name>AUTENTICADO</role-name>
</security-role>
<error-page>
<error-code>403</error-code>
<location>/erro403.jsp</location>
</error-page>
</web-app>

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 13


Como usar JAAS com Tomcat 6.0

6) Referências consultadas

Create an anonymous authentication module


http://www.javaworld.com/javaworld/jw-03-2005/jw-0307-captcha.html

JAAS Book
http://www.jaasbook.com/

JAAS Security in Action


http://www.devx.com/getHelpOn/Article/9915/1954?pf=true

Java Authentication and Authorization Service (JAAS)


http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html

Java Authentication and Authorization Service (JAAS) in Java 2, Standard Edition (J2SE) 1.4
http://java.sun.com/developer/technicalArticles/Security/jaasv2/

Java SE Security
http://java.sun.com/javase/technologies/security/

Java security, Part 2: Authentication and authorization


https://www6.software.ibm.com/developerworks/education/j-sec2/index.html

Realm Configuration HOW-TO


http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html

Tutorial do JAAS
http://guj.com.br/java.tutorial.artigo.184.1.guj

@ 2008 Prof. Antonio Passos (http://blog.antoniopassos.pro.br) Página 14