Struts 2 - Autenticação [Resolvido]

Sou novo no Struts 2 (Webwork :D) e gostaria de saber qual é a melhor forma nesta framework de verificar se um usuário está autenticado. Não vou utilizar JAAS.
Normalmente, após a verificação de usuário / senha no login, colocamos um objeto com os dados do usuário na sessão e, durante a navegação, ficamos verificando se esse objeto existe ou não na sessão. Caso não exista, redirecionamos o usuário para a página de login.

Qual é a melhor forma de fazer isso no Struts 2?

Cara da uma lida em “Filtros”, que é um tipo de servlet, ele pode ajudar você nessa dúvida, pois todo servlet que voce precisar vai passar por esse filtro e por ele mesmo você pode ou não deixar o usuário prosseguir.

Até mais

Ricardo Cabral

Sim, essa é uma opção mas no Struts 2 posso usar Interceptors.
Posso por exemplo configurar um Interceptor que será executado antes da chamada a qualquer action.
A dúvida é se já existe algo pronto no Struts 2 ou alguma forma utilizando seus recursos para fazer isso.

Uma opção que estou cogitando é a implementação de um Interceptor que faça isso mas antes de reinventar a roda prefiro perguntar.

Olá,
[quote] Normalmente, após a verificação de usuário / senha no login, colocamos um objeto com os dados do usuário na sessão e[/quote] Vc. está usando ORM .??? se não, está autentinando aonde…???..

[quote] Uma opção que estou cogitando é a implementação de um Interceptor que faça isso mas antes de reinventar a roda prefiro perguntar.[/quote] Mais vc. vai estar interceptando a invocação de uma ação (action) isto é vc. deve definir códigos os que serão executados antes e depois de uma ação.
http://www.guj.com.br/java.tutorial.artigo.135.1.guj
http://www.guj.com.br/content/articles/webwork/webwork.pdf

Sim, estou utilizando JPA obtendo o usuário de um banco.

Apenas não sei qual a forma mais comum no Struts 2 / Webwork de colocar o objeto usuário na sessão e depois ficar verificando, a cada request, se ele existe ou não na sessão.

Sei que existem diversas formas de fazer isso como por exemplo utilizando filtros ou com outras técnicas mas no Struts 2 / WebWork não sei se já tem algo pronto.

Posso dizer que minha pergunta foi levantada pelo meu desconhecimento na utilização do Struts 2 / WebWork

William

Esses tutoriais que você me indicou possuem tudo que preciso.

Muito obrigado amigo

Pessoal

Voltei com o tópico. Achei que tinha encontrado a solução mas os tutoriais passados pelo Willian se referem a uma versão mais antiga do WebWork.
O problema é que no Struts 2 não temos mais o container de IOC.

Se alguém tiver algum exemplo de autenticação utilizando o Struts 2 (sem utilizar JAAS) por favor, poderia me passar?

Não sei se devo utilizar o Spring ou o Struts 2 já tem algo pronto.

Eu acredito que não tenha pronto.

Mas você fazer um interceptor sem muita dificuldade.

Pelo o que eu entendi seria algo mais ou menos assim:

User user = ActionContext.getContext().getSession().get("user");
if (user == null) {
       return Action.LOGIN;
}

return action.invoke();

E como vc faz redirect after login?

E como vc protege o acesso direto ao jsp?

1- Refaço a url com as informações do ActionInvocation;
2- Coloco a url na session;
3- Redireciono para a action de login;
4- Se login OK, coloco a url em um atributo da action e retiro da session;
5- E no xwork: <result name=“success”>${url}</result>

A ultima vez que fiz foi mais ou menos dessa forma, pode ser que eu tenha esquecido algum passo.

Eu geralmente coloco os arquivos jsp dentro do diretório WEB-INF, mas se for o caso de estarem fora, um interceptor/filter deve resolver esse problema.

Consegui fazer o modelo de autenticação no Struts 2 de uma forma que ficou bem legal.
Criei o interceptor abaixo:

public class ApplicationSecurityInterceptor implements Interceptor {

	private static final long serialVersionUID = 4194206894614545639L;

	public void destroy() {
	}

	public void init() {
	}

	public String intercept(ActionInvocation invocation) throws Exception {
		Action action = (Action) invocation.getAction();

        SessionMap session = (SessionMap) ActionContext.getContext().get(ActionContext.SESSION);
        SessaoUsuario usuarioSession = (SessaoUsuario) session.get(Constants.SESSAO_USUARIO_KEY);

        // Se a action não implementar a interface DisableSecurityAction é feito o teste de sessão do usuário
		if (!(action instanceof DisableSecurityAction) && (usuarioSession == null)) {
            return Action.LOGIN;
	    }
		
		// Se a action implementar a interface UsuarioAware coloca a sessão do usuário na action
		if(action instanceof SessaoUsuarioAware) {
			((SessaoUsuarioAware)action).setSessaoUsuario(usuarioSession);
		}
		
        return invocation.invoke();
	}
}

Criei uma marker interface chamada DisableSecurityAction. Toda action que implementar essa interface não terá validação de segurança.

Criei a interface abaixo que, ao ser implementada pela action, possibilita o acesso a sessão do usuário.

public interface SessaoUsuarioAware {

	public void setSessaoUsuario(SessaoUsuario sessaoUsuario);
}

Na action de login efetuo a verificação do usuário e sua senha e coloco o usuário na sessão.

Para finalizar criei um global-result chamado “login” que é chamado pela classe ApplicationSecurityInterceptor quando o usuário não é encontrado na sessão. Este result envia o usuário para a página de login.

Achei bem interessante a implementação do LeoNicolas de autenticação.
Estou fazendo algo parecido… com o struts 2 tb…

Porem, não estou conseguindo fazer com q os interceptors sejam executados quando as actions anotadas são chamadas…

Alguem já criou um interceptor para uma action anotada?

Ok… depois d suar um pouco consegui…

Se alguem um dia precisar…

Tipo… no struts.xml

<package name="meuPacote" extends="struts-default">
  <interceptors>
    <interceptor name="security" class="pacote.MeuSecurityInterceptor" />
    <interceptor-stack name="meuStack">
      <interceptor-ref name="security" />
      <interceptor-ref name="defaultStack" />
    </interceptor-stack>
  </interceptors>
  <default-interceptor-ref name="meuStack" />
</package>

O detalhe que faltava na action: ParentPackage

@Results({
  @Result(name = SUCCESS, value = "index.jsp") 
})
@ParentPackage("meuPacote")
public class Index {

  public String execute() {
    return SUCCESS;
  }

}

olá!

sobre o código do LeoNicolas, alguém sabe me dizer o que é SessaoUsuario ?

obrigado.

Acredito q é um Bean que ele armazena algumas informações do usuário logado na sessão. Acho q ele guarda o usuário q está logado… não?

No meu caso, baseado no exemplo do LeoNicolas, e depois de um tempo… o meu codigo foi mudando… rs…
Hj o meu SessaoUsuario eh algo assim:

public class SessaoUsuario implements Serializable {
  
  private Long id;
  private String sessionId;
  private String enderecoIP;
  private boolean logado;
  private boolean trocarSenha;
  private String menuHtml;
  private String layoutCSSHtml;
  private Local localizacao;

  public SessaoUsuario(){
  }

  // gets e sets

}

Eu tirei o meu Usuario dai… por conta de uns probleminhas q tive…

Qdo eu preciso do usuario, eu busco no banco, onde ele estah relacionado com o sessionId desse SessaoUsuario.