Trocar de Usuário durante uma sessão - Struts

Olá,

quero implementar uma funcionalidade na qual quando determinado usuário loga no sistema ele pode possuir ou não permissao para trocar de sessao e logar como algum outro determinado usuário, obtendo assim todos os privilégios que esse usuário possui.

Isso será feito através de um menu, no qual conterá a lista de todos os usuários que ele pode logar, caso existe mais que um.

Os usuários que tiveram sua conta delegada para determinado usuário não poderá acessar o sistema até que essa permissão acabe.

Segue o codigo abaixo do FiltroAcesso acredito que a melhor forma de implementar seria somente nessa classe, ja que ela que determina quem esta logado e quais os privilegios, fico no aguardo das sugestões e também códigos que façam a troca de usuario na sessao, não encontrei nada a respeito.

package br.gov.exercito.sped.administracao.sessao;



import java.io.IOException;

import java.util.ArrayList;

import java.util.List;



import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;



import br.gov.exercito.sped.util.Constantes;

import br.gov.exercito.sped.util.Util;



import com.miranteinfo.soap.light.SOAPLight;

import com.miranteinfo.soap.light.SOAPLightException;

import com.miranteinfo.xml.util.MElement;

import com.novell.ldap.LDAPConnection;

import com.novell.ldap.LDAPException;



/**

 * Intercepta todas as chamadas ao servidor para verificar se o usuário, ao acessar um endereço

 * protegido, está logado e se possui direiro sobre o recurso específico. No caso de não estar

 * logado, o usuário é redirecionado para a página de login. Se ele não possuir direito sobre o

 * recurso em questão, então devolve um erro http.

 * 

 * @author Daniel C. Bordin - SeguroRural

 * 

 * Adicionada a funcionalidade de autenticação em um servidor LDAP da seguinte forma: 1. É

 * verificada a autenticidade do usuário; 2. Se autêntico, os dados do usuário contidos no LDAP são

 * usados para atualizar os dados do usuário no sistema (SPED); 3. Se autêntico e o usuário não

 * existir no SPED, então é criado um usuário no SPED com aqueles dados e dados padrões para os que

 * existirem no LDAP; 4. Se não autêntico, é gerado um erro e volta-se para a tela de logon.

 * 

 * @author Ricardo Campos - SPED

 * @version 30/06/2005

 */

public class FiltroAcesso implements Filter {



    private final List listaPath = new ArrayList();



    private final List listaPerfil = new ArrayList();

    

    private final List listaDelegados = new ArrayList();

    

    private static String RESPONSAVEL;



    private static final String[] PUBLICO = new String[0];



    private static final String[] USUARIO_AUTENTICADO = new String[0];



    private static final String[] ADMINISTRADOR = new String[0];



    private static final String LOGIN_ADMIN = "admin";



    /**

     * Configurações de acesso.

     * 

     * Inicialmente, todos os recursos são bloqueados. Aqueles que precisarem ser acessados, devem

     * ser configurados.

     * 

     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)

     */

    public void init(FilterConfig conf) throws ServletException {



        addDireito("/design/", PUBLICO);

        addDireito(Constantes.SESSAO_URL_LOGON, PUBLICO);

        addDireito(Constantes.SESSAO_URL_LOGOFF, PUBLICO);



        // LOGADOS = admin, protocolista ou convencional

        addDireito("/", USUARIO_AUTENTICADO);

    }



    /**

     * @throws SOAPLightException

     * @throws IllegalArgumentException

     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,

     *      javax.servlet.ServletResponse, javax.servlet.FilterChain)

     */

    public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain chain)

            throws IOException, ServletException, IllegalArgumentException {



        HttpServletRequest request = ((HttpServletRequest) sreq);

        HttpServletResponse response = ((HttpServletResponse) sresp);



        RequestWrapper reqW = new RequestWrapper(request);



        String path = reqW.getServletPath();



        response.setHeader("Cache-Control", "no-cache");

        response.setHeader("Pragma", "no-cache");

        response.setDateHeader("Expires", 0);



        if (path.endsWith("j_security_check")) {



            // pagina de logon, form com usuario e senha enviado.

            try {

                efetuarLogon(reqW, response);



                if (reqW.getParameter("j_username") != null) {



                    // isso só pode ser feito em um request wrapper!!



                    //reqW.setRemoteUser(reqW.getParameter("j_username"));

                	//RESPONSAVEL = reqW.getParameter("j_username");

                	reqW.setRemoteUser("brigadeiro");

                	

                }



            } catch (Exception e) {

                throw new ServletException("Problemas autenticando o usuário.", e);

            }

            return;

        }



        // tratamento de uma página qualquer do sistema.



        String[] direitosNecessario = getDireito(path);



        boolean acessoOk = false;



        if (direitosNecessario == PUBLICO) {

            acessoOk = true;



        } else {

            HttpSession session = reqW.getSession(false);



            if (session == null || reqW.getRemoteUser() == null) {

                // usuário não autenticado, redirecionar para logon



                String enderecoOriginal = reqW.getRequestURI();



                if (reqW.getQueryString() != null) {

                    enderecoOriginal += '?' + reqW.getQueryString();

                }



                reqW.getSession().setAttribute("enderecoOriginal", enderecoOriginal);



                response.sendRedirect(reqW.getContextPath() + Constantes.SESSAO_URL_LOGON);

                return;

            }



            if (direitosNecessario == null) {

                // não pode acessar já que não foram configurados os direitos.



            } else if (direitosNecessario == USUARIO_AUTENTICADO) {

                acessoOk = true;



            }



            // filtro da migração

            

            String contexto = reqW.getContextPath();



            if (contexto.endsWith(Constantes.CONTEXTO_MIGRACAO)) {

            	MElement usuario = null;

                // usuário entrando no site de migração. só pode admin!

            	try {

            		usuario = Util.carregarUsuario(reqW.getRemoteUser());

            		

            	} catch (SOAPLightException e) {

            		response.sendRedirect("/design/erro.jsp");

            	}

            	String codPerfil = usuario.getValor("cd-perfil");

            	

                if (!codPerfil.equals(Constantes.USUARIO_PERFIL_ADMINISTRADOR+"")) {



                    session.invalidate();

                    

                    throw new ServletException("Sem permissão. "

                            + "Apenas um usuário administrador pode executar a migração.");

                }

            }

        }



        if (acessoOk && path.endsWith("/")) {

            // evita a lista do conteudo do diretório

            acessoOk = false;

        }



        if (acessoOk) {

            //chain.doFilter(sreq, sresp);

            chain.doFilter(reqW, sresp);



        } else {

            response.sendError(HttpServletResponse.SC_FORBIDDEN,

                    "Usuario não logado ou sem direito de acesso ao recurso " + path);

        }

    }



    private void efetuarLogon(HttpServletRequest req, HttpServletResponse resp) throws Exception {



        if (!"POST".equals(req.getMethod())) {

            // alguém mandou os dados via GET

            resp.sendError(HttpServletResponse.SC_FORBIDDEN,

                    "Autenticação requisitada incorretamente. Por favor, use a tela de logon.");

            return;

        }



        String user = req.getParameter("j_username");

        String pass = req.getParameter("j_password");



        if ((user == null) || (pass == null)) {

            resp.sendRedirect(req.getContextPath() + Constantes.SESSAO_URL_LOGON + "?erro=1");

            return;

        }



        if (!autenticarLDAP(user, pass)) {



            resp.sendRedirect(req.getContextPath() + Constantes.SESSAO_URL_LOGON + "?erro=1");



        } else {



        	if (!sincronizarLDAP(user)){

        		resp.sendRedirect(req.getContextPath() + Constantes.SESSAO_URL_LOGON + "?erro=1");



        	}else{



	            String enderecoOriginal = (String) req.getSession().getAttribute("enderecoOriginal");

	

	            if (enderecoOriginal == null) {

	                enderecoOriginal = req.getContextPath();

	            } else {

	                req.getSession().removeAttribute("enderecoOriginal");

	            }

	

	            resp.sendRedirect(enderecoOriginal);

	            req.getSession().setAttribute("remoteUser", user);

        	}

        }

    }



    /**

     * @param user

     * @param pass

     * @return

     * @throws Exception

     */

    private boolean autenticarLDAP(String user, String pass) throws Exception {



        boolean autenticou = false;



        LDAPConnection conn = new LDAPConnection();



        // autenticar ao servidor

        conn.connect(Util.getLDAPServerName(), Util.getLDAPServerPort());



        try {

            conn.bind(LDAPConnection.LDAP_V3, "cn=" + user + "," + Util.getLDAPBaseDn(), pass

                    .getBytes("UTF8"));



        } catch (LDAPException e) {

            if (e.getResultCode() != Constantes.LDAP_CREDENCIAIS_INVALIDAS) {

                // a exceção com o código acima representa a de login ou senha

                // inválidos.

                throw e;

            }

        }



        autenticou = conn.isBound();        



        conn.disconnect();



        return autenticou;

    }



    /**

     * Chama a feature para sincronização LDAP <-->BD.

     * 

     * @param user

     * @throws Exception

     */

    private boolean sincronizarLDAP(String user)  {



        MElement req = MElement

                .newInstance("br_gov_exercito-sped_administracao-sessao-sincronizarLDAP");



        req.addElement("nome-usuario", user);

        try {

        	new SOAPLight(req).call().getBody();

        } catch (Throwable t){

        	return false;

        }

        return true;

    }



    private void addDireito(String path, String[] roles) {

        listaPath.add(path);

        listaPerfil.add(roles);

    }



    private String[] getDireito(String path) {

        for (int i = 0; i < listaPath.size(); i++) {

            if (path.startsWith((String) listaPath.get(i))) {

                return (String[]) listaPerfil.get(i);

            }

        }

        return null;

    }



    /**

     * @see javax.servlet.Filter#destroy()

     */

    public void destroy() {

    }

}

Abraços