Boa Tarde Galera,
Estou com um enorme problema que não estou conseguindo resolver ja faz um tempão, gostaria de saber se alguem por ae utiliza JAAS + JBOSS 4.2.3 + JSF para me dar uma força em relação ao logout do usuario autenticado ou algo parecido
Em relação a autenticação esta funcionando tudo perfeitamente tanto para user tanto para roles, o meu grande problema é em relação ao logout.
Quando vou efetuar o logout o meu ‘Subject’ sempre esta retonando null. Não consegui verificar o problema em nenhum lugar em foruns e outros. Quando eu realizo o login o Subject esta sendo preenchido corretamente.
Eu até consigo invalidar a sessão web, utilizando o metodo request.getSession().invalidate();
O problema esta na proxima tentativa de logar com o mesmo usuario, aparentemente o mesmo não foi morto no servidor e o processo não passa novamente pelo autenticação JAAS.
Existe alguma configuração para isto? ou algo que posso estar fazendo para matar de vez esta sessão no servidor
Segue o meu codigo de autenticação que foi baseado em um tutorial do guj.
Ele esta como managedBean com escopo de sessão.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.security.Principal;
import java.security.acl.Group;
import java.sql.*;
import java.util.*;
import javax.naming.*;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.security.jacc.PolicyContextException;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import org.jboss.security.SimpleGroup;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.security.auth.login.LoginContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.ws.WebServiceContext;
import org.apache.poi.hssf.record.formula.functions.Request;
import org.jboss.management.j2ee.SessionBean;
import org.jboss.security.auth.spi.AbstractServerLoginModule;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
import javax.security.jacc.PolicyContext;
public class LoginModuleSecurity implements LoginModule {
private static Logger logger = Logger.getLogger(LoginModule.class.getName());
private boolean commitSucceeded = false;
private boolean succeeded = false;
private User userPrincipal;
private Set roles = new HashSet();
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private String dataSourceName;
private String sqlUser;// = "select DS_SENHA, ID_USUARIO from TB_USUARIO where NM_LOGIN=?";
//private String sqlRoles = "select role from tb_usuario_roles where login=?";
private String sqlRoles;// = "select NM_ROLE from TB_USUARIO_ROLE where ID_USUARIO=?";
private String nmUsuarioLogado;//Seta a descrição do usuario logado na sessão
private int idUsuarioLogado;//Seta o codigo do usuario logado na sessão
private int idEmpresaUsuarioLogado;//Seta o codigo da empresa do usuario logado na sessão
private FacesContext context = null;
private HttpSession session = null;
public LoginModuleSecurity() {
}
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
logger.info("--> Passando no passo 1");
this.setSubject(subject);
this.setCallbackHandler(callbackHandler);
this.setSharedState(sharedState);
dataSourceName = (String) options.get("dataSourceName");
sqlUser = (String) options.get("sqlUser");
sqlRoles = (String) options.get("sqlRoles");
}
public boolean login() throws LoginException {
logger.info("--> ENTRANDO no passo 2");
// recupera o login e senha informados no form
getUsernamePassword();
Connection conn = null;
try {
// obtem a conexão
try {
Context initContext = new InitialContext();
DataSource ds = (DataSource) initContext.lookup(dataSourceName);
conn = ds.getConnection();
} catch (NamingException e) {
succeeded = false;
throw new LoginException("Erro ao recuperar DataSource: " + e.getClass().getName() + ": " + e.getMessage());
} catch (SQLException e) {
succeeded = false;
throw new LoginException("Erro ao obter conexão: " + e.getClass().getName() + ": " + e.getMessage());
}
// valida o usuario
validaUsuario(conn);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
throw new LoginException("Erro na validação do usuario: " + e.getClass().getName() + ": " + e.getMessage());
}
}
}
// acidiona o usuario e roles no mapa de compartilhamento
getSharedState().put("javax.security.auth.principal", userPrincipal);
getSharedState().put("javax.security.auth.roles", roles);
return true;
}
public boolean commit() throws LoginException {
logger.info("--> Passando no passo 3");
final SimpleGroup userRoles = new SimpleGroup("Roles");
// adiciona o usuario no principals
if (userPrincipal != null && !subject.getPrincipals().contains(userPrincipal)) {
getSubject().getPrincipals().add(userPrincipal);
}
// adiciona as roles no principals
if (getRoles() != null) {
Iterator it = getRoles().iterator();
while (it.hasNext()) {
Role role = (Role) it.next();
if (!subject.getPrincipals().contains(role)) {
//subject.getPrincipals().add(role);
userRoles.addMember(role);
}
}
getSubject().getPrincipals().add(userRoles);
}
commitSucceeded = true;
return true;
}
public boolean abort() throws LoginException {
if (!succeeded) {
return false;
} else if (succeeded && !commitSucceeded) {
succeeded = false;
} else {
succeeded = false;
logout();
}
this.setSubject(null);
this.setCallbackHandler(null);
this.setSharedState(null);
this.setRoles(new HashSet());
return succeeded;
}
public boolean logout() throws LoginException {
if (subject != null) {
subject.getPrincipals().removeAll(roles);
subject.getPrincipals().remove(userPrincipal);
getSubject().getPrincipals().clear();
}
succeeded = false;
succeeded = commitSucceeded;
return true;
}
/**
* Valida login e senha no banco
*/
private void validaUsuario(Connection conn) throws LoginException {
logger.info("--> Passando no passo 4");
logger.info("Teste");
String senhaBanco = null;
PreparedStatement statement = null;
ResultSet rs = null;
int id_usuario;
String nm_usuario;
int id_empresa;
try {
statement = conn.prepareStatement(sqlUser);
statement.setString(1, loginInformado);
rs = statement.executeQuery();
if (rs.next()) {
senhaBanco = rs.getString("CC_SENHA");
id_usuario = rs.getInt("ID_USUARIO");
nm_usuario = rs.getString("NM_USUARIO");
id_empresa = rs.getInt("ID_EMPRESA");
logger.info("ID DO USUARIO RECUPERADO DO BANCO : " + id_usuario);
} else {
succeeded = false;
throw new LoginException("Usuário não localizado.");
}
} catch (SQLException e) {
succeeded = false;
throw new LoginException("Erro ao abrir sessão: "
+ e.getClass().getName() + ": " + e.getMessage());
} finally {
try {
if (rs != null) {
rs.close();
}
if (statement != null) {
statement.close();
}
} catch (Exception e) {
logger.info("Erro Geral: " + e.getMessage());
}
}
if (senhaInformado.equals(senhaBanco)) {
setUserPrincipal(new User(loginInformado));
this.getUserPrincipal().setId_usuario(id_usuario);
this.getUserPrincipal().setNm_usuario(nm_usuario);
this.getUserPrincipal().setId_empresa(id_empresa);
recuperaRoles(conn, id_usuario);
getUserPrincipal().setRoles(getRoles());
return;
} else {
throw new LoginException("Senha Inválida.");
}
}
/**
* Recupera as roles no banco
*/
public void recuperaRoles(Connection conn, int id_usuario) throws LoginException {
logger.info("--> Passando no passo 5");
PreparedStatement statement = null;
ResultSet rs = null;
try {
statement = conn.prepareStatement(sqlRoles);
statement.setInt(1, id_usuario);
rs = statement.executeQuery();
while (rs.next()) {
getRoles().add(new Role(rs.getString(1)));
System.out.println(rs.getString(1));
}
roles.add(new Role("LOGADO"));
} catch (SQLException e) {
succeeded = false;
throw new LoginException("Erro ao recuperar roles: " + e.getClass().getName() + ": " + e.getMessage());
} finally {
try {
if (rs != null) {
rs.close();
}
if (statement != null) {
statement.close();
}
} catch (Exception e) {
}
}
}
/**
* Login do usuário.
*/
protected String loginInformado;
/**
* Senha do usuário.
*/
protected String senhaInformado;
/**
* Obtem o login e senha digitados
*/
protected void getUsernamePassword() throws LoginException {
logger.info("------------------------------------> Passando no passo 5");
if (getCallbackHandler() == null) {
throw new LoginException("Error: no CallbackHandler available to garner authentication information from the user");
}
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("Login");
callbacks[1] = new PasswordCallback("Senha", false);
try {
getCallbackHandler().handle(callbacks);
loginInformado = ((NameCallback) callbacks[0]).getName();
char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
senhaInformado = new String(tmpPassword);
((PasswordCallback) callbacks[1]).clearPassword();
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() + " not available to garner authentication information from the user");
}
}
/**
* @return the roles
*/
public Set getRoles() {
return roles;
}
/**
* @param roles the roles to set
*/
public void setRoles(Set roles) {
this.roles = roles;
}
/**
* @return the nmUsuarioLogado
*/
public String getNmUsuarioLogado() {
return nmUsuarioLogado;
}
/**
* @param nmUsuarioLogado the nmUsuarioLogado to set
*/
public void setNmUsuarioLogado(String nmUsuarioLogado) {
this.nmUsuarioLogado = nmUsuarioLogado;
}
/**
* @return the idUsuarioLogado
*/
public int getIdUsuarioLogado() {
return idUsuarioLogado;
}
/**
* @return the idEmpresaUsuarioLogado
*/
public int getIdEmpresaUsuarioLogado() {
return idEmpresaUsuarioLogado;
}
/**
* @param idEmpresaUsuarioLogado the idEmpresaUsuarioLogado to set
*/
public void setIdEmpresaUsuarioLogado(int idEmpresaUsuarioLogado) {
this.idEmpresaUsuarioLogado = idEmpresaUsuarioLogado;
}
/**
* @param idUsuarioLogado the idUsuarioLogado to set
*/
public void setIdUsuarioLogado(int idUsuarioLogado) {
this.idUsuarioLogado = idUsuarioLogado;
}
/**
* @return the userPrincipal
*/
public User getUserPrincipal() {
return userPrincipal;
}
/**
* @param userPrincipal the userPrincipal to set
*/
public void setUserPrincipal(User userPrincipal) {
this.userPrincipal = userPrincipal;
}
/**
* @return the subject
*/
public Subject getSubject() {
return subject;
}
/**
* @param subject the subject to set
*/
public void setSubject(Subject subject) {
this.subject = subject;
}
/**
* @return the callbackHandler
*/
public CallbackHandler getCallbackHandler() {
return callbackHandler;
}
/**
* @param callbackHandler the callbackHandler to set
*/
public void setCallbackHandler(CallbackHandler callbackHandler) {
this.callbackHandler = callbackHandler;
}
/**
* @return the sharedState
*/
public Map getSharedState() {
return sharedState;
}
/**
* @param sharedState the sharedState to set
*/
public void setSharedState(Map sharedState) {
this.sharedState = sharedState;
}
}
Configuração no JBOSS - login-config.xml
<application-policy name="WSLoginModule">
<authentication>
<login-module code="br.com.seguranca.LoginModuleSecurity" flag="required">
<!-- <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">-->
<module-option name="dataSourceName">java:/JNDISorce</module-option>
<module-option name="sqlUser">select * from TB_USUARIO where NM_LOGIN=?</module-option>
<module-option name="sqlRoles">select NM_ROLE from TB_USUARIO_ROLE where ID_USUARIO=?</module-option>
<module-option name="unauthenticatedIdentity">anonymous</module-option>
</login-module>
</authentication>
</application-policy>
Acredito que seja alguma coisa referente a ambiente, ?
Espero que alguem jah passou por isso e possa me dar um caminho a ser seguido hehe…
Abcss T+